* config/xtensa/xtensa.c (xtensa_expand_builtin): Use CALL_EXPR_FN.
[official-gcc.git] / libgfortran / io / write.c
blobecee33032c941f2cc0c32578af114ea8b9a82534
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)
10 any later version.
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
19 executable.)
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. */
31 #include "config.h"
32 #include <assert.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include "libgfortran.h"
38 #include "io.h"
40 #define star_fill(p, n) memset(p, '*', n)
43 typedef enum
44 { SIGN_NONE, SIGN_MINUS, SIGN_PLUS }
45 sign_t;
48 void
49 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
51 int wlen;
52 char *p;
54 wlen = f->u.string.length < 0 ? len : f->u.string.length;
56 #ifdef HAVE_CRLF
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";
63 int i, q, bytes;
64 q = bytes = 0;
66 /* Write out any padding if needed. */
67 if (len < wlen)
69 p = write_block (dtp, wlen - len);
70 if (p == NULL)
71 return;
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. */
81 if (bytes > 0)
83 p = write_block (dtp, bytes);
84 if (p == NULL)
85 return;
86 memcpy (p, &source[q], bytes);
87 q += bytes;
88 bytes = 0;
91 /* Write out the CR_LF sequence. */
92 q++;
93 p = write_block (dtp, 2);
94 if (p == NULL)
95 return;
96 memcpy (p, crlf, 2);
98 else
99 bytes++;
102 /* Write out any remaining bytes if no LF was found. */
103 if (bytes > 0)
105 p = write_block (dtp, bytes);
106 if (p == NULL)
107 return;
108 memcpy (p, &source[q], bytes);
111 else
113 #endif
114 p = write_block (dtp, wlen);
115 if (p == NULL)
116 return;
118 if (wlen < len)
119 memcpy (p, source, wlen);
120 else
122 memset (p, ' ', wlen - len);
123 memcpy (p + wlen - len, source, len);
125 #ifdef HAVE_CRLF
127 #endif
130 static GFC_INTEGER_LARGEST
131 extract_int (const void *p, int len)
133 GFC_INTEGER_LARGEST i = 0;
135 if (p == NULL)
136 return i;
138 switch (len)
140 case 1:
142 GFC_INTEGER_1 tmp;
143 memcpy ((void *) &tmp, p, len);
144 i = tmp;
146 break;
147 case 2:
149 GFC_INTEGER_2 tmp;
150 memcpy ((void *) &tmp, p, len);
151 i = tmp;
153 break;
154 case 4:
156 GFC_INTEGER_4 tmp;
157 memcpy ((void *) &tmp, p, len);
158 i = tmp;
160 break;
161 case 8:
163 GFC_INTEGER_8 tmp;
164 memcpy ((void *) &tmp, p, len);
165 i = tmp;
167 break;
168 #ifdef HAVE_GFC_INTEGER_16
169 case 16:
171 GFC_INTEGER_16 tmp;
172 memcpy ((void *) &tmp, p, len);
173 i = tmp;
175 break;
176 #endif
177 default:
178 internal_error (NULL, "bad integer kind");
181 return i;
184 static GFC_UINTEGER_LARGEST
185 extract_uint (const void *p, int len)
187 GFC_UINTEGER_LARGEST i = 0;
189 if (p == NULL)
190 return i;
192 switch (len)
194 case 1:
196 GFC_INTEGER_1 tmp;
197 memcpy ((void *) &tmp, p, len);
198 i = (GFC_UINTEGER_1) tmp;
200 break;
201 case 2:
203 GFC_INTEGER_2 tmp;
204 memcpy ((void *) &tmp, p, len);
205 i = (GFC_UINTEGER_2) tmp;
207 break;
208 case 4:
210 GFC_INTEGER_4 tmp;
211 memcpy ((void *) &tmp, p, len);
212 i = (GFC_UINTEGER_4) tmp;
214 break;
215 case 8:
217 GFC_INTEGER_8 tmp;
218 memcpy ((void *) &tmp, p, len);
219 i = (GFC_UINTEGER_8) tmp;
221 break;
222 #ifdef HAVE_GFC_INTEGER_16
223 case 16:
225 GFC_INTEGER_16 tmp;
226 memcpy ((void *) &tmp, p, len);
227 i = (GFC_UINTEGER_16) tmp;
229 break;
230 #endif
231 default:
232 internal_error (NULL, "bad integer kind");
235 return i;
238 static GFC_REAL_LARGEST
239 extract_real (const void *p, int len)
241 GFC_REAL_LARGEST i = 0;
242 switch (len)
244 case 4:
246 GFC_REAL_4 tmp;
247 memcpy ((void *) &tmp, p, len);
248 i = tmp;
250 break;
251 case 8:
253 GFC_REAL_8 tmp;
254 memcpy ((void *) &tmp, p, len);
255 i = tmp;
257 break;
258 #ifdef HAVE_GFC_REAL_10
259 case 10:
261 GFC_REAL_10 tmp;
262 memcpy ((void *) &tmp, p, len);
263 i = tmp;
265 break;
266 #endif
267 #ifdef HAVE_GFC_REAL_16
268 case 16:
270 GFC_REAL_16 tmp;
271 memcpy ((void *) &tmp, p, len);
272 i = tmp;
274 break;
275 #endif
276 default:
277 internal_error (NULL, "bad real kind");
279 return i;
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. */
286 static sign_t
287 calculate_sign (st_parameter_dt *dtp, int negative_flag)
289 sign_t s = SIGN_NONE;
291 if (negative_flag)
292 s = SIGN_MINUS;
293 else
294 switch (dtp->u.p.sign_status)
296 case SIGN_SP:
297 s = SIGN_PLUS;
298 break;
299 case SIGN_SS:
300 s = SIGN_NONE;
301 break;
302 case SIGN_S:
303 s = options.optional_plus ? SIGN_PLUS : SIGN_NONE;
304 break;
307 return s;
311 /* Returns the value of 10**d. */
313 static GFC_REAL_LARGEST
314 calculate_exp (int d)
316 int i;
317 GFC_REAL_LARGEST r = 1.0;
319 for (i = 0; i< (d >= 0 ? d : -d); i++)
320 r *= 10;
322 r = (d >= 0) ? r : 1.0 / r;
324 return 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 */
345 static fnode *
346 calculate_G_format (st_parameter_dt *dtp, const fnode *f,
347 GFC_REAL_LARGEST value, int *num_blank)
349 int e = f->u.real.e;
350 int d = f->u.real.d;
351 int w = f->u.real.w;
352 fnode *newf;
353 GFC_REAL_LARGEST m, exp_d;
354 int low, high, mid;
355 int ubound, lbound;
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;
369 newf->u.real.w = w;
370 newf->u.real.d = d;
371 newf->u.real.e = e;
372 *num_blank = 0;
373 return newf;
376 /* Use binary search to find the data magnitude range. */
377 mid = 0;
378 low = 0;
379 high = d + 1;
380 lbound = 0;
381 ubound = d + 1;
383 while (low <= high)
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);
391 if (m < temp)
393 ubound = mid;
394 if (ubound == lbound + 1)
395 break;
396 high = mid - 1;
398 else if (m > temp)
400 lbound = mid;
401 if (ubound == lbound + 1)
403 mid ++;
404 break;
406 low = mid + 1;
408 else
409 break;
412 /* Pad with blanks where the exponent would be. */
413 if (e < 0)
414 *num_blank = 4;
415 else
416 *num_blank = e + 2;
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;
422 /* Special case. */
423 if (m == 0.0)
424 newf->u.real.d = d - 1;
425 else
426 newf->u.real.d = - (mid - d - 1);
428 /* For F editing, the scale factor is ignored. */
429 dtp->u.p.scale_factor = 0;
430 return newf;
434 /* Output a real number according to its format which is FMT_G free. */
436 static void
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
441 #else
442 # define MIN_FIELD_WIDTH 31
443 #endif
444 #define STR(x) STR1(x)
445 #define STR1(x) #x
446 /* This must be large enough to accurately hold any value. */
447 char buffer[MIN_FIELD_WIDTH+1];
448 char *out;
449 char *digits;
450 int e;
451 char expchar;
452 format_token ft;
453 int w;
454 int d;
455 int edigits;
456 int ndigits;
457 /* Number of digits before the decimal point. */
458 int nbefore;
459 /* Number of zeros after the decimal point. */
460 int nzero;
461 /* Number of digits after the decimal point. */
462 int nafter;
463 /* Number of zeros after the decimal point, whatever the precision. */
464 int nzero_real;
465 int leadzero;
466 int nblanks;
467 int i;
468 sign_t sign;
469 double abslog;
471 ft = f->format;
472 w = f->u.real.w;
473 d = f->u.real.d;
475 nzero_real = -1;
478 /* We should always know the field width and precision. */
479 if (d < 0)
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);
486 if (value < 0)
487 value = -value;
489 /* Special case when format specifies no digits after the decimal point. */
490 if (d == 0 && ft == FMT_F)
492 if (value < 0.5)
493 value = 0.0;
494 else if (value < 1.0)
495 value = value + 0.5;
498 /* Printf always prints at least two exponent digits. */
499 if (value == 0)
500 edigits = 2;
501 else
503 #if defined(HAVE_GFC_REAL_10) || defined(HAVE_GFC_REAL_16)
504 abslog = fabs((double) log10l(value));
505 #else
506 abslog = fabs(log10(value));
507 #endif
508 if (abslog < 100)
509 edigits = 2;
510 else
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;
520 else
522 /* We know the number of digits, so can let printf do the rounding
523 for us. */
524 if (ft == FMT_ES)
525 ndigits = d + 1;
526 else
527 ndigits = d;
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
533 * digits follow it
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. */
559 if (value == 0.0)
560 e = 0;
562 /* Normalize the fractional component. */
563 buffer[2] = buffer[1];
564 digits = &buffer[2];
566 /* Figure out where to place the decimal point. */
567 switch (ft)
569 case FMT_F:
570 nbefore = e + dtp->u.p.scale_factor;
571 if (nbefore < 0)
573 nzero = -nbefore;
574 nzero_real = nzero;
575 if (nzero > d)
576 nzero = d;
577 nafter = d - nzero;
578 nbefore = 0;
580 else
582 nzero = 0;
583 nafter = d;
585 expchar = 0;
586 break;
588 case FMT_E:
589 case FMT_D:
590 i = dtp->u.p.scale_factor;
591 if (value != 0.0)
592 e -= i;
593 if (i < 0)
595 nbefore = 0;
596 nzero = -i;
597 nafter = d + i;
599 else if (i > 0)
601 nbefore = i;
602 nzero = 0;
603 nafter = (d - i) + 1;
605 else /* i == 0 */
607 nbefore = 0;
608 nzero = 0;
609 nafter = d;
612 if (ft == FMT_E)
613 expchar = 'E';
614 else
615 expchar = 'D';
616 break;
618 case FMT_EN:
619 /* The exponent must be a multiple of three, with 1-3 digits before
620 the decimal point. */
621 if (value != 0.0)
622 e--;
623 if (e >= 0)
624 nbefore = e % 3;
625 else
627 nbefore = (-e) % 3;
628 if (nbefore != 0)
629 nbefore = 3 - nbefore;
631 e -= nbefore;
632 nbefore++;
633 nzero = 0;
634 nafter = d;
635 expchar = 'E';
636 break;
638 case FMT_ES:
639 if (value != 0.0)
640 e--;
641 nbefore = 1;
642 nzero = 0;
643 nafter = d;
644 expchar = 'E';
645 break;
647 default:
648 /* Should never happen. */
649 internal_error (&dtp->common, "Unexpected format token");
652 /* Round the value. */
653 if (nbefore + nafter == 0)
655 ndigits = 0;
656 if (nzero_real == d && digits[0] >= '5')
658 /* We rounded to zero but shouldn't have */
659 nzero--;
660 nafter = 1;
661 digits[0] = '1';
662 ndigits = 1;
665 else if (nbefore + nafter < ndigits)
667 ndigits = nbefore + nafter;
668 i = ndigits;
669 if (digits[i] >= '5')
671 /* Propagate the carry. */
672 for (i--; i >= 0; i--)
674 if (digits[i] != '9')
676 digits[i]++;
677 break;
679 digits[i] = '0';
682 if (i < 0)
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. */
687 digits--;
688 digits[0] = '1';
689 if (ft == FMT_F)
691 if (nzero > 0)
693 nzero--;
694 nafter++;
696 else
697 nbefore++;
699 else if (ft == FMT_EN)
701 nbefore++;
702 if (nbefore == 4)
704 nbefore = 1;
705 e += 3;
708 else
709 e++;
714 /* Calculate the format of the exponent field. */
715 if (expchar)
717 edigits = 1;
718 for (i = abs (e); i >= 10; i /= 10)
719 edigits++;
721 if (f->u.real.e < 0)
723 /* Width not specified. Must be no more than 3 digits. */
724 if (e > 999 || e < -999)
725 edigits = -1;
726 else
728 edigits = 4;
729 if (e > 99 || e < -99)
730 expchar = ' ';
733 else
735 /* Exponent width specified, check it is wide enough. */
736 if (edigits > f->u.real.e)
737 edigits = -1;
738 else
739 edigits = f->u.real.e + 2;
742 else
743 edigits = 0;
745 /* Pick a field size if none was specified. */
746 if (w <= 0)
747 w = nbefore + nzero + nafter + (sign != SIGN_NONE ? 2 : 1);
749 /* Create the ouput buffer. */
750 out = write_block (dtp, w);
751 if (out == NULL)
752 return;
754 /* Zero values always output as positive, even if the value was negative
755 before rounding. */
756 for (i = 0; i < ndigits; i++)
758 if (digits[i] != '0')
759 break;
761 if (i == ndigits)
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)
767 nblanks--;
769 /* Check the value fits in the specified field width. */
770 if (nblanks < 0 || edigits == -1)
772 star_fill (out, w);
773 return;
776 /* See if we have space for a zero before the decimal point. */
777 if (nbefore == 0 && nblanks > 0)
779 leadzero = 1;
780 nblanks--;
782 else
783 leadzero = 0;
785 /* Pad to full field width. */
788 if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
790 memset (out, ' ', nblanks);
791 out += nblanks;
794 /* Output the initial sign (if any). */
795 if (sign == SIGN_PLUS)
796 *(out++) = '+';
797 else if (sign == SIGN_MINUS)
798 *(out++) = '-';
800 /* Output an optional leading zero. */
801 if (leadzero)
802 *(out++) = '0';
804 /* Output the part before the decimal point, padding with zeros. */
805 if (nbefore > 0)
807 if (nbefore > ndigits)
808 i = ndigits;
809 else
810 i = nbefore;
812 memcpy (out, digits, i);
813 while (i < nbefore)
814 out[i++] = '0';
816 digits += i;
817 ndigits -= i;
818 out += nbefore;
820 /* Output the decimal point. */
821 *(out++) = '.';
823 /* Output leading zeros after the decimal point. */
824 if (nzero > 0)
826 for (i = 0; i < nzero; i++)
827 *(out++) = '0';
830 /* Output digits after the decimal point, padding with zeros. */
831 if (nafter > 0)
833 if (nafter > ndigits)
834 i = ndigits;
835 else
836 i = nafter;
838 memcpy (out, digits, i);
839 while (i < nafter)
840 out[i++] = '0';
842 digits += i;
843 ndigits -= i;
844 out += nafter;
847 /* Output the exponent. */
848 if (expchar)
850 if (expchar != ' ')
852 *(out++) = expchar;
853 edigits--;
855 #if HAVE_SNPRINTF
856 snprintf (buffer, sizeof (buffer), "%+0*d", edigits, e);
857 #else
858 sprintf (buffer, "%+0*d", edigits, e);
859 #endif
860 memcpy (out, buffer, edigits);
863 if (dtp->u.p.no_leading_blank)
865 out += edigits;
866 memset( out , ' ' , nblanks );
867 dtp->u.p.no_leading_blank = 0;
869 #undef STR
870 #undef STR1
871 #undef MIN_FIELD_WIDTH
875 void
876 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
878 char *p;
879 GFC_INTEGER_LARGEST n;
881 p = write_block (dtp, f->u.w);
882 if (p == NULL)
883 return;
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. */
892 static void
893 write_float (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
895 GFC_REAL_LARGEST n;
896 int nb =0, res, save_scale_factor;
897 char * p, fin;
898 fnode *f2 = NULL;
900 n = extract_real (source, len);
902 if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z)
904 res = isfinite (n);
905 if (res == 0)
907 nb = f->u.real.w;
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' */
912 if (nb == 0) nb = 4;
913 p = write_block (dtp, nb);
914 if (p == NULL)
915 return;
916 if (nb < 3)
918 memset (p, '*',nb);
919 return;
922 memset(p, ' ', nb);
923 res = !isnan (n);
924 if (res != 0)
926 if (signbit(n))
929 /* If the sign is negative and the width is 3, there is
930 insufficient room to output '-Inf', so output asterisks */
932 if (nb == 3)
934 memset (p, '*',nb);
935 return;
938 /* The negative sign is mandatory */
940 fin = '-';
942 else
944 /* The positive sign is optional, but we output it for
945 consistency */
947 fin = '+';
949 if (nb > 8)
951 /* We have room, so output 'Infinity' */
953 memcpy(p + nb - 8, "Infinity", 8);
954 else
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 */
962 else if (nb > 8)
963 p[nb - 9] = fin; /* Put the sign in front of Infinity */
965 else
966 memcpy(p + nb - 3, "NaN", 3);
967 return;
971 if (f->format != FMT_G)
972 output_float (dtp, f, n);
973 else
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;
979 if (f2 != NULL)
980 free_mem(f2);
982 if (nb > 0)
984 p = write_block (dtp, nb);
985 if (p == NULL)
986 return;
987 memset (p, ' ', nb);
993 static void
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;
999 char *p;
1000 const char *q;
1001 char itoa_buf[GFC_BTOA_BUF_SIZE];
1003 w = f->u.integer.w;
1004 m = f->u.integer.m;
1006 n = extract_uint (source, len);
1008 /* Special case: */
1010 if (m == 0 && n == 0)
1012 if (w == 0)
1013 w = 1;
1015 p = write_block (dtp, w);
1016 if (p == NULL)
1017 return;
1019 memset (p, ' ', w);
1020 goto done;
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
1027 print something. */
1029 if (w == 0)
1030 w = ((digits < m) ? m : digits);
1032 p = write_block (dtp, w);
1033 if (p == NULL)
1034 return;
1036 nzero = 0;
1037 if (digits < m)
1038 nzero = m - digits;
1040 /* See if things will work. */
1042 nblank = w - (nzero + digits);
1044 if (nblank < 0)
1046 star_fill (p, w);
1047 goto done;
1051 if (!dtp->u.p.no_leading_blank)
1053 memset (p, ' ', nblank);
1054 p += nblank;
1055 memset (p, '0', nzero);
1056 p += nzero;
1057 memcpy (p, q, digits);
1059 else
1061 memset (p, '0', nzero);
1062 p += nzero;
1063 memcpy (p, q, digits);
1064 p += digits;
1065 memset (p, ' ', nblank);
1066 dtp->u.p.no_leading_blank = 0;
1069 done:
1070 return;
1073 static void
1074 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
1075 int len,
1076 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
1078 GFC_INTEGER_LARGEST n = 0;
1079 int w, m, digits, nsign, nzero, nblank;
1080 char *p;
1081 const char *q;
1082 sign_t sign;
1083 char itoa_buf[GFC_BTOA_BUF_SIZE];
1085 w = f->u.integer.w;
1086 m = f->u.integer.m;
1088 n = extract_int (source, len);
1090 /* Special case: */
1092 if (m == 0 && n == 0)
1094 if (w == 0)
1095 w = 1;
1097 p = write_block (dtp, w);
1098 if (p == NULL)
1099 return;
1101 memset (p, ' ', w);
1102 goto done;
1105 sign = calculate_sign (dtp, n < 0);
1106 if (n < 0)
1107 n = -n;
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
1115 print something. */
1117 if (w == 0)
1118 w = ((digits < m) ? m : digits) + nsign;
1120 p = write_block (dtp, w);
1121 if (p == NULL)
1122 return;
1124 nzero = 0;
1125 if (digits < m)
1126 nzero = m - digits;
1128 /* See if things will work. */
1130 nblank = w - (nsign + nzero + digits);
1132 if (nblank < 0)
1134 star_fill (p, w);
1135 goto done;
1138 memset (p, ' ', nblank);
1139 p += nblank;
1141 switch (sign)
1143 case SIGN_PLUS:
1144 *p++ = '+';
1145 break;
1146 case SIGN_MINUS:
1147 *p++ = '-';
1148 break;
1149 case SIGN_NONE:
1150 break;
1153 memset (p, '0', nzero);
1154 p += nzero;
1156 memcpy (p, q, digits);
1158 done:
1159 return;
1163 /* Convert unsigned octal to ascii. */
1165 static const char *
1166 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1168 char *p;
1170 assert (len >= GFC_OTOA_BUF_SIZE);
1172 if (n == 0)
1173 return "0";
1175 p = buffer + GFC_OTOA_BUF_SIZE - 1;
1176 *p = '\0';
1178 while (n != 0)
1180 *--p = '0' + (n & 7);
1181 n >>= 3;
1184 return p;
1188 /* Convert unsigned binary to ascii. */
1190 static const char *
1191 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1193 char *p;
1195 assert (len >= GFC_BTOA_BUF_SIZE);
1197 if (n == 0)
1198 return "0";
1200 p = buffer + GFC_BTOA_BUF_SIZE - 1;
1201 *p = '\0';
1203 while (n != 0)
1205 *--p = '0' + (n & 1);
1206 n >>= 1;
1209 return p;
1213 void
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);
1220 void
1221 write_b (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1223 write_int (dtp, f, p, len, btoa);
1227 void
1228 write_o (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1230 write_int (dtp, f, p, len, otoa);
1233 void
1234 write_z (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1236 write_int (dtp, f, p, len, xtoa);
1240 void
1241 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1243 write_float (dtp, f, p, len);
1247 void
1248 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1250 write_float (dtp, f, p, len);
1254 void
1255 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1257 write_float (dtp, f, p, len);
1261 void
1262 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1264 write_float (dtp, f, p, len);
1268 void
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. */
1277 void
1278 write_x (st_parameter_dt *dtp, int len, int nspaces)
1280 char *p;
1282 p = write_block (dtp, len);
1283 if (p == NULL)
1284 return;
1286 if (nspaces > 0)
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. */
1297 static int
1298 write_char (st_parameter_dt *dtp, char c)
1300 char *p;
1302 p = write_block (dtp, 1);
1303 if (p == NULL)
1304 return 1;
1306 *p = c;
1308 return 0;
1312 /* Write a list-directed logical value. */
1314 static void
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. */
1323 static void
1324 write_integer (st_parameter_dt *dtp, const char *source, int length)
1326 char *p;
1327 const char *q;
1328 int digits;
1329 int width;
1330 char itoa_buf[GFC_ITOA_BUF_SIZE];
1332 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1334 switch (length)
1336 case 1:
1337 width = 4;
1338 break;
1340 case 2:
1341 width = 6;
1342 break;
1344 case 4:
1345 width = 11;
1346 break;
1348 case 8:
1349 width = 20;
1350 break;
1352 default:
1353 width = 0;
1354 break;
1357 digits = strlen (q);
1359 if (width < digits)
1360 width = digits;
1361 p = write_block (dtp, width);
1362 if (p == NULL)
1363 return;
1364 if (dtp->u.p.no_leading_blank)
1366 memcpy (p, q, digits);
1367 memset (p + digits, ' ', width - digits);
1369 else
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. */
1380 static void
1381 write_character (st_parameter_dt *dtp, const char *source, int length)
1383 int i, extra;
1384 char *p, d;
1386 switch (dtp->u.p.current_unit->flags.delim)
1388 case DELIM_APOSTROPHE:
1389 d = '\'';
1390 break;
1391 case DELIM_QUOTE:
1392 d = '"';
1393 break;
1394 default:
1395 d = ' ';
1396 break;
1399 if (d == ' ')
1400 extra = 0;
1401 else
1403 extra = 2;
1405 for (i = 0; i < length; i++)
1406 if (source[i] == d)
1407 extra++;
1410 p = write_block (dtp, length + extra);
1411 if (p == NULL)
1412 return;
1414 if (d == ' ')
1415 memcpy (p, source, length);
1416 else
1418 *p++ = d;
1420 for (i = 0; i < length; i++)
1422 *p++ = source[i];
1423 if (source[i] == d)
1424 *p++ = d;
1427 *p = d;
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). */
1436 static void
1437 write_real (st_parameter_dt *dtp, const char *source, int length)
1439 fnode f ;
1440 int org_scale = dtp->u.p.scale_factor;
1441 f.format = FMT_G;
1442 dtp->u.p.scale_factor = 1;
1443 switch (length)
1445 case 4:
1446 f.u.real.w = 14;
1447 f.u.real.d = 7;
1448 f.u.real.e = 2;
1449 break;
1450 case 8:
1451 f.u.real.w = 23;
1452 f.u.real.d = 15;
1453 f.u.real.e = 3;
1454 break;
1455 case 10:
1456 f.u.real.w = 28;
1457 f.u.real.d = 19;
1458 f.u.real.e = 4;
1459 break;
1460 case 16:
1461 f.u.real.w = 43;
1462 f.u.real.d = 34;
1463 f.u.real.e = 4;
1464 break;
1465 default:
1466 internal_error (&dtp->common, "bad real kind");
1467 break;
1469 write_float (dtp, &f, source , length);
1470 dtp->u.p.scale_factor = org_scale;
1474 static void
1475 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1477 if (write_char (dtp, '('))
1478 return;
1479 write_real (dtp, source, kind);
1481 if (write_char (dtp, ','))
1482 return;
1483 write_real (dtp, source + size / 2, kind);
1485 write_char (dtp, ')');
1489 /* Write the separator between items. */
1491 static void
1492 write_separator (st_parameter_dt *dtp)
1494 char *p;
1496 p = write_block (dtp, options.separator_len);
1497 if (p == NULL)
1498 return;
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
1506 with strings. */
1508 static void
1509 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1510 size_t size)
1512 if (dtp->u.p.current_unit == NULL)
1513 return;
1515 if (dtp->u.p.first_item)
1517 dtp->u.p.first_item = 0;
1518 write_char (dtp, ' ');
1520 else
1522 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1523 dtp->u.p.current_unit->flags.delim != DELIM_NONE)
1524 write_separator (dtp);
1527 switch (type)
1529 case BT_INTEGER:
1530 write_integer (dtp, p, kind);
1531 break;
1532 case BT_LOGICAL:
1533 write_logical (dtp, p, kind);
1534 break;
1535 case BT_CHARACTER:
1536 write_character (dtp, p, kind);
1537 break;
1538 case BT_REAL:
1539 write_real (dtp, p, kind);
1540 break;
1541 case BT_COMPLEX:
1542 write_complex (dtp, p, kind, size);
1543 break;
1544 default:
1545 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1548 dtp->u.p.char_flag = (type == BT_CHARACTER);
1552 void
1553 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1554 size_t size, size_t nelems)
1556 size_t elem;
1557 char *tmp;
1559 tmp = (char *) p;
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);
1569 /* NAMELIST OUTPUT
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
1577 component.
1578 base_name = the full name for a derived type, including qualifiers
1579 if any.
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
1585 the list. */
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)
1596 int rep_ctr;
1597 int num;
1598 int nml_carry;
1599 index_type len;
1600 index_type obj_size;
1601 index_type nelem;
1602 index_type dim_i;
1603 index_type clen;
1604 index_type elem_ctr;
1605 index_type obj_name_len;
1606 void * p ;
1607 char cup;
1608 char * obj_name;
1609 char * ext_name;
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)
1619 #ifdef HAVE_CRLF
1620 write_character (dtp, "\r\n ", 3);
1621 #else
1622 write_character (dtp, "\n ", 2);
1623 #endif
1624 len = 0;
1625 if (base)
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. */
1644 num = 1;
1646 len = obj->len;
1648 switch (obj->type)
1651 case GFC_DTYPE_REAL:
1652 obj_size = size_from_real_kind (len);
1653 break;
1655 case GFC_DTYPE_COMPLEX:
1656 obj_size = size_from_complex_kind (len);
1657 break;
1659 case GFC_DTYPE_CHARACTER:
1660 obj_size = obj->string_length;
1661 break;
1663 default:
1664 obj_size = len;
1667 if (obj->var_rank)
1668 obj_size = obj->size;
1670 /* Set the index vector and count the number of elements. */
1672 nelem = 1;
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. */
1681 rep_ctr = 1;
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);
1690 p += offset;
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 ))
1698 rep_ctr++;
1701 /* Execute a repeated output. Note the flag no_leading_blank that
1702 is used in the functions used to output the intrinsic types. */
1704 else
1706 if (rep_ctr > 1)
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;
1712 num++;
1714 /* Output the data, if an intrinsic type, or recurse into this
1715 routine to treat derived types. */
1717 switch (obj->type)
1720 case GFC_DTYPE_INTEGER:
1721 write_integer (dtp, p, len);
1722 break;
1724 case GFC_DTYPE_LOGICAL:
1725 write_logical (dtp, p, len);
1726 break;
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);
1734 break;
1736 case GFC_DTYPE_REAL:
1737 write_real (dtp, p, len);
1738 break;
1740 case GFC_DTYPE_COMPLEX:
1741 dtp->u.p.no_leading_blank = 0;
1742 num++;
1743 write_complex (dtp, p, len, obj_size);
1744 break;
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
1751 nml_write_obj.
1752 obj_name = the derived type name with no qualifiers but %
1753 appended. This is used to identify the
1754 components. */
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
1762 + 1);
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) ? ")" : ",");
1778 /* Now obj_name. */
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);
1791 cmp = retval)
1793 retval = nml_write_obj (dtp, cmp,
1794 (index_type)(p - obj->mem_pos),
1795 obj, ext_name);
1798 free_mem (obj_name);
1799 free_mem (ext_name);
1800 goto obj_loop;
1802 default:
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);
1812 if (num > 5)
1814 num = 0;
1815 #ifdef HAVE_CRLF
1816 write_character (dtp, "\r\n ", 3);
1817 #else
1818 write_character (dtp, "\n ", 2);
1819 #endif
1821 rep_ctr = 1;
1824 /* Cycle through and increment the index vector. */
1826 obj_loop:
1828 nml_carry = 1;
1829 for (dim_i = 0; nml_carry && (dim_i < obj->var_rank); dim_i++)
1831 obj->ls[dim_i].idx += nml_carry ;
1832 nml_carry = 0;
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;
1836 nml_carry = 1;
1841 /* Return a pointer beyond the furthest object accessed. */
1843 return retval;
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. */
1851 void
1852 namelist_write (st_parameter_dt *dtp)
1854 namelist_info * t1, *t2, *dummy = NULL;
1855 index_type i;
1856 index_type dummy_offset = 0;
1857 char c;
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;
1865 switch (tmp_delim)
1867 case (DELIM_QUOTE):
1868 dtp->u.p.nml_delim = '"';
1869 break;
1871 case (DELIM_APOSTROPHE):
1872 dtp->u.p.nml_delim = '\'';
1873 break;
1875 default:
1876 dtp->u.p.nml_delim = '\0';
1877 break;
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;
1893 while (t1 != NULL)
1895 t2 = t1;
1896 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
1899 #ifdef HAVE_CRLF
1900 write_character (dtp, " /\r\n", 5);
1901 #else
1902 write_character (dtp, " /\n", 4);
1903 #endif
1905 /* Recover the original delimiter. */
1907 dtp->u.p.current_unit->flags.delim = tmp_delim;
1910 #undef NML_DIGITS