minloc1.m4: Update copyright year and ajust headers order.
[official-gcc.git] / libgfortran / io / write.c
blob062a4c74bb9cbce63f03c05fbde32a3775ef0b36
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)
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 "io.h"
32 #include <assert.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <stdlib.h>
37 #define star_fill(p, n) memset(p, '*', n)
40 typedef enum
41 { SIGN_NONE, SIGN_MINUS, SIGN_PLUS }
42 sign_t;
45 void
46 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
48 int wlen;
49 char *p;
51 wlen = f->u.string.length < 0 ? len : f->u.string.length;
53 #ifdef HAVE_CRLF
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";
60 int i, q, bytes;
61 q = bytes = 0;
63 /* Write out any padding if needed. */
64 if (len < wlen)
66 p = write_block (dtp, wlen - len);
67 if (p == NULL)
68 return;
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. */
78 if (bytes > 0)
80 p = write_block (dtp, bytes);
81 if (p == NULL)
82 return;
83 memcpy (p, &source[q], bytes);
84 q += bytes;
85 bytes = 0;
88 /* Write out the CR_LF sequence. */
89 q++;
90 p = write_block (dtp, 2);
91 if (p == NULL)
92 return;
93 memcpy (p, crlf, 2);
95 else
96 bytes++;
99 /* Write out any remaining bytes if no LF was found. */
100 if (bytes > 0)
102 p = write_block (dtp, bytes);
103 if (p == NULL)
104 return;
105 memcpy (p, &source[q], bytes);
108 else
110 #endif
111 p = write_block (dtp, wlen);
112 if (p == NULL)
113 return;
115 if (wlen < len)
116 memcpy (p, source, wlen);
117 else
119 memset (p, ' ', wlen - len);
120 memcpy (p + wlen - len, source, len);
122 #ifdef HAVE_CRLF
124 #endif
127 static GFC_INTEGER_LARGEST
128 extract_int (const void *p, int len)
130 GFC_INTEGER_LARGEST i = 0;
132 if (p == NULL)
133 return i;
135 switch (len)
137 case 1:
139 GFC_INTEGER_1 tmp;
140 memcpy ((void *) &tmp, p, len);
141 i = tmp;
143 break;
144 case 2:
146 GFC_INTEGER_2 tmp;
147 memcpy ((void *) &tmp, p, len);
148 i = tmp;
150 break;
151 case 4:
153 GFC_INTEGER_4 tmp;
154 memcpy ((void *) &tmp, p, len);
155 i = tmp;
157 break;
158 case 8:
160 GFC_INTEGER_8 tmp;
161 memcpy ((void *) &tmp, p, len);
162 i = tmp;
164 break;
165 #ifdef HAVE_GFC_INTEGER_16
166 case 16:
168 GFC_INTEGER_16 tmp;
169 memcpy ((void *) &tmp, p, len);
170 i = tmp;
172 break;
173 #endif
174 default:
175 internal_error (NULL, "bad integer kind");
178 return i;
181 static GFC_UINTEGER_LARGEST
182 extract_uint (const void *p, int len)
184 GFC_UINTEGER_LARGEST i = 0;
186 if (p == NULL)
187 return i;
189 switch (len)
191 case 1:
193 GFC_INTEGER_1 tmp;
194 memcpy ((void *) &tmp, p, len);
195 i = (GFC_UINTEGER_1) tmp;
197 break;
198 case 2:
200 GFC_INTEGER_2 tmp;
201 memcpy ((void *) &tmp, p, len);
202 i = (GFC_UINTEGER_2) tmp;
204 break;
205 case 4:
207 GFC_INTEGER_4 tmp;
208 memcpy ((void *) &tmp, p, len);
209 i = (GFC_UINTEGER_4) tmp;
211 break;
212 case 8:
214 GFC_INTEGER_8 tmp;
215 memcpy ((void *) &tmp, p, len);
216 i = (GFC_UINTEGER_8) tmp;
218 break;
219 #ifdef HAVE_GFC_INTEGER_16
220 case 16:
222 GFC_INTEGER_16 tmp;
223 memcpy ((void *) &tmp, p, len);
224 i = (GFC_UINTEGER_16) tmp;
226 break;
227 #endif
228 default:
229 internal_error (NULL, "bad integer kind");
232 return i;
235 static GFC_REAL_LARGEST
236 extract_real (const void *p, int len)
238 GFC_REAL_LARGEST i = 0;
239 switch (len)
241 case 4:
243 GFC_REAL_4 tmp;
244 memcpy ((void *) &tmp, p, len);
245 i = tmp;
247 break;
248 case 8:
250 GFC_REAL_8 tmp;
251 memcpy ((void *) &tmp, p, len);
252 i = tmp;
254 break;
255 #ifdef HAVE_GFC_REAL_10
256 case 10:
258 GFC_REAL_10 tmp;
259 memcpy ((void *) &tmp, p, len);
260 i = tmp;
262 break;
263 #endif
264 #ifdef HAVE_GFC_REAL_16
265 case 16:
267 GFC_REAL_16 tmp;
268 memcpy ((void *) &tmp, p, len);
269 i = tmp;
271 break;
272 #endif
273 default:
274 internal_error (NULL, "bad real kind");
276 return i;
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. */
283 static sign_t
284 calculate_sign (st_parameter_dt *dtp, int negative_flag)
286 sign_t s = SIGN_NONE;
288 if (negative_flag)
289 s = SIGN_MINUS;
290 else
291 switch (dtp->u.p.sign_status)
293 case SIGN_SP:
294 s = SIGN_PLUS;
295 break;
296 case SIGN_SS:
297 s = SIGN_NONE;
298 break;
299 case SIGN_S:
300 s = options.optional_plus ? SIGN_PLUS : SIGN_NONE;
301 break;
304 return s;
308 /* Returns the value of 10**d. */
310 static GFC_REAL_LARGEST
311 calculate_exp (int d)
313 int i;
314 GFC_REAL_LARGEST r = 1.0;
316 for (i = 0; i< (d >= 0 ? d : -d); i++)
317 r *= 10;
319 r = (d >= 0) ? r : 1.0 / r;
321 return 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 */
342 static fnode *
343 calculate_G_format (st_parameter_dt *dtp, const fnode *f,
344 GFC_REAL_LARGEST value, int *num_blank)
346 int e = f->u.real.e;
347 int d = f->u.real.d;
348 int w = f->u.real.w;
349 fnode *newf;
350 GFC_REAL_LARGEST m, exp_d;
351 int low, high, mid;
352 int ubound, lbound;
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;
366 newf->u.real.w = w;
367 newf->u.real.d = d;
368 newf->u.real.e = e;
369 *num_blank = 0;
370 return newf;
373 /* Use binary search to find the data magnitude range. */
374 mid = 0;
375 low = 0;
376 high = d + 1;
377 lbound = 0;
378 ubound = d + 1;
380 while (low <= high)
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);
388 if (m < temp)
390 ubound = mid;
391 if (ubound == lbound + 1)
392 break;
393 high = mid - 1;
395 else if (m > temp)
397 lbound = mid;
398 if (ubound == lbound + 1)
400 mid ++;
401 break;
403 low = mid + 1;
405 else
406 break;
409 /* Pad with blanks where the exponent would be. */
410 if (e < 0)
411 *num_blank = 4;
412 else
413 *num_blank = e + 2;
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;
419 /* Special case. */
420 if (m == 0.0)
421 newf->u.real.d = d - 1;
422 else
423 newf->u.real.d = - (mid - d - 1);
425 /* For F editing, the scale factor is ignored. */
426 dtp->u.p.scale_factor = 0;
427 return newf;
431 /* Output a real number according to its format which is FMT_G free. */
433 static void
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
438 #else
439 # define MIN_FIELD_WIDTH 31
440 #endif
441 #define STR(x) STR1(x)
442 #define STR1(x) #x
443 /* This must be large enough to accurately hold any value. */
444 char buffer[MIN_FIELD_WIDTH+1];
445 char *out;
446 char *digits;
447 int e;
448 char expchar;
449 format_token ft;
450 int w;
451 int d;
452 int edigits;
453 int ndigits;
454 /* Number of digits before the decimal point. */
455 int nbefore;
456 /* Number of zeros after the decimal point. */
457 int nzero;
458 /* Number of digits after the decimal point. */
459 int nafter;
460 /* Number of zeros after the decimal point, whatever the precision. */
461 int nzero_real;
462 int leadzero;
463 int nblanks;
464 int i;
465 int sign_bit;
466 sign_t sign;
468 ft = f->format;
469 w = f->u.real.w;
470 d = f->u.real.d;
472 nzero_real = -1;
475 /* We should always know the field width and precision. */
476 if (d < 0)
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);
484 if (value < 0)
485 value = -value;
487 /* Special case when format specifies no digits after the decimal point. */
488 if (d == 0 && ft == FMT_F)
490 if (value < 0.5)
491 value = 0.0;
492 else if (value < 1.0)
493 value = value + 0.5;
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. */
498 edigits=4;
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;
506 else
508 /* We know the number of digits, so can let printf do the rounding
509 for us. */
510 if (ft == FMT_ES)
511 ndigits = d + 1;
512 else
513 ndigits = d;
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
519 * digits follow it
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.
534 #ifdef HAVE_SNPRINTF
535 snprintf (buffer, sizeof (buffer), "%+-#" STR(MIN_FIELD_WIDTH) ".*"
536 GFC_REAL_LARGEST_FORMAT "e", ndigits - 1, value);
537 #else
538 sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*"
539 GFC_REAL_LARGEST_FORMAT "e", ndigits - 1, value);
540 #endif
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. */
550 if (value == 0.0)
552 e = 0;
553 if (compile_options.sign_zero == 1)
554 sign = calculate_sign (dtp, sign_bit);
555 else
556 sign = calculate_sign (dtp, 0);
559 /* Normalize the fractional component. */
560 buffer[2] = buffer[1];
561 digits = &buffer[2];
563 /* Figure out where to place the decimal point. */
564 switch (ft)
566 case FMT_F:
567 nbefore = e + dtp->u.p.scale_factor;
568 if (nbefore < 0)
570 nzero = -nbefore;
571 nzero_real = nzero;
572 if (nzero > d)
573 nzero = d;
574 nafter = d - nzero;
575 nbefore = 0;
577 else
579 nzero = 0;
580 nafter = d;
582 expchar = 0;
583 break;
585 case FMT_E:
586 case FMT_D:
587 i = dtp->u.p.scale_factor;
588 if (value != 0.0)
589 e -= i;
590 if (i < 0)
592 nbefore = 0;
593 nzero = -i;
594 nafter = d + i;
596 else if (i > 0)
598 nbefore = i;
599 nzero = 0;
600 nafter = (d - i) + 1;
602 else /* i == 0 */
604 nbefore = 0;
605 nzero = 0;
606 nafter = d;
609 if (ft == FMT_E)
610 expchar = 'E';
611 else
612 expchar = 'D';
613 break;
615 case FMT_EN:
616 /* The exponent must be a multiple of three, with 1-3 digits before
617 the decimal point. */
618 if (value != 0.0)
619 e--;
620 if (e >= 0)
621 nbefore = e % 3;
622 else
624 nbefore = (-e) % 3;
625 if (nbefore != 0)
626 nbefore = 3 - nbefore;
628 e -= nbefore;
629 nbefore++;
630 nzero = 0;
631 nafter = d;
632 expchar = 'E';
633 break;
635 case FMT_ES:
636 if (value != 0.0)
637 e--;
638 nbefore = 1;
639 nzero = 0;
640 nafter = d;
641 expchar = 'E';
642 break;
644 default:
645 /* Should never happen. */
646 internal_error (&dtp->common, "Unexpected format token");
649 /* Round the value. */
650 if (nbefore + nafter == 0)
652 ndigits = 0;
653 if (nzero_real == d && digits[0] >= '5')
655 /* We rounded to zero but shouldn't have */
656 nzero--;
657 nafter = 1;
658 digits[0] = '1';
659 ndigits = 1;
662 else if (nbefore + nafter < ndigits)
664 ndigits = nbefore + nafter;
665 i = ndigits;
666 if (digits[i] >= '5')
668 /* Propagate the carry. */
669 for (i--; i >= 0; i--)
671 if (digits[i] != '9')
673 digits[i]++;
674 break;
676 digits[i] = '0';
679 if (i < 0)
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. */
684 digits--;
685 digits[0] = '1';
686 if (ft == FMT_F)
688 if (nzero > 0)
690 nzero--;
691 nafter++;
693 else
694 nbefore++;
696 else if (ft == FMT_EN)
698 nbefore++;
699 if (nbefore == 4)
701 nbefore = 1;
702 e += 3;
705 else
706 e++;
711 /* Calculate the format of the exponent field. */
712 if (expchar)
714 edigits = 1;
715 for (i = abs (e); i >= 10; i /= 10)
716 edigits++;
718 if (f->u.real.e < 0)
720 /* Width not specified. Must be no more than 3 digits. */
721 if (e > 999 || e < -999)
722 edigits = -1;
723 else
725 edigits = 4;
726 if (e > 99 || e < -99)
727 expchar = ' ';
730 else
732 /* Exponent width specified, check it is wide enough. */
733 if (edigits > f->u.real.e)
734 edigits = -1;
735 else
736 edigits = f->u.real.e + 2;
739 else
740 edigits = 0;
742 /* Pick a field size if none was specified. */
743 if (w <= 0)
744 w = nbefore + nzero + nafter + (sign != SIGN_NONE ? 2 : 1);
746 /* Create the ouput buffer. */
747 out = write_block (dtp, w);
748 if (out == NULL)
749 return;
751 /* Zero values always output as positive, even if the value was negative
752 before rounding. */
753 for (i = 0; i < ndigits; i++)
755 if (digits[i] != '0')
756 break;
758 if (i == ndigits)
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);
764 else
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)
771 nblanks--;
773 /* Check the value fits in the specified field width. */
774 if (nblanks < 0 || edigits == -1)
776 star_fill (out, w);
777 return;
780 /* See if we have space for a zero before the decimal point. */
781 if (nbefore == 0 && nblanks > 0)
783 leadzero = 1;
784 nblanks--;
786 else
787 leadzero = 0;
789 /* Pad to full field width. */
791 if ( ( nblanks > 0 ) && !dtp->u.p.no_leading_blank)
793 memset (out, ' ', nblanks);
794 out += nblanks;
797 /* Output the initial sign (if any). */
798 if (sign == SIGN_PLUS)
799 *(out++) = '+';
800 else if (sign == SIGN_MINUS)
801 *(out++) = '-';
803 /* Output an optional leading zero. */
804 if (leadzero)
805 *(out++) = '0';
807 /* Output the part before the decimal point, padding with zeros. */
808 if (nbefore > 0)
810 if (nbefore > ndigits)
812 i = ndigits;
813 memcpy (out, digits, i);
814 ndigits = 0;
815 while (i < nbefore)
816 out[i++] = '0';
818 else
820 i = nbefore;
821 memcpy (out, digits, i);
822 ndigits -= i;
825 digits += i;
826 out += nbefore;
828 /* Output the decimal point. */
829 *(out++) = '.';
831 /* Output leading zeros after the decimal point. */
832 if (nzero > 0)
834 for (i = 0; i < nzero; i++)
835 *(out++) = '0';
838 /* Output digits after the decimal point, padding with zeros. */
839 if (nafter > 0)
841 if (nafter > ndigits)
842 i = ndigits;
843 else
844 i = nafter;
846 memcpy (out, digits, i);
847 while (i < nafter)
848 out[i++] = '0';
850 digits += i;
851 ndigits -= i;
852 out += nafter;
855 /* Output the exponent. */
856 if (expchar)
858 if (expchar != ' ')
860 *(out++) = expchar;
861 edigits--;
863 #if HAVE_SNPRINTF
864 snprintf (buffer, sizeof (buffer), "%+0*d", edigits, e);
865 #else
866 sprintf (buffer, "%+0*d", edigits, e);
867 #endif
868 memcpy (out, buffer, edigits);
871 if (dtp->u.p.no_leading_blank)
873 out += edigits;
874 memset( out , ' ' , nblanks );
875 dtp->u.p.no_leading_blank = 0;
877 #undef STR
878 #undef STR1
879 #undef MIN_FIELD_WIDTH
883 void
884 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
886 char *p;
887 GFC_INTEGER_LARGEST n;
889 p = write_block (dtp, f->u.w);
890 if (p == NULL)
891 return;
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. */
900 static void
901 write_float (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
903 GFC_REAL_LARGEST n;
904 int nb =0, res, save_scale_factor;
905 char * p, fin;
906 fnode *f2 = NULL;
908 n = extract_real (source, len);
910 if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z)
912 res = isfinite (n);
913 if (res == 0)
915 nb = f->u.real.w;
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' */
920 if (nb == 0) nb = 4;
921 p = write_block (dtp, nb);
922 if (p == NULL)
923 return;
924 if (nb < 3)
926 memset (p, '*',nb);
927 return;
930 memset(p, ' ', nb);
931 res = !isnan (n);
932 if (res != 0)
934 if (signbit(n))
937 /* If the sign is negative and the width is 3, there is
938 insufficient room to output '-Inf', so output asterisks */
940 if (nb == 3)
942 memset (p, '*',nb);
943 return;
946 /* The negative sign is mandatory */
948 fin = '-';
950 else
952 /* The positive sign is optional, but we output it for
953 consistency */
955 fin = '+';
957 if (nb > 8)
959 /* We have room, so output 'Infinity' */
961 memcpy(p + nb - 8, "Infinity", 8);
962 else
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 */
970 else if (nb > 8)
971 p[nb - 9] = fin; /* Put the sign in front of Infinity */
973 else
974 memcpy(p + nb - 3, "NaN", 3);
975 return;
979 if (f->format != FMT_G)
980 output_float (dtp, f, n);
981 else
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;
987 if (f2 != NULL)
988 free_mem(f2);
990 if (nb > 0)
992 p = write_block (dtp, nb);
993 if (p == NULL)
994 return;
995 memset (p, ' ', nb);
1001 static void
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;
1007 char *p;
1008 const char *q;
1009 char itoa_buf[GFC_BTOA_BUF_SIZE];
1011 w = f->u.integer.w;
1012 m = f->u.integer.m;
1014 n = extract_uint (source, len);
1016 /* Special case: */
1018 if (m == 0 && n == 0)
1020 if (w == 0)
1021 w = 1;
1023 p = write_block (dtp, w);
1024 if (p == NULL)
1025 return;
1027 memset (p, ' ', w);
1028 goto done;
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
1035 print something. */
1037 if (w == 0)
1038 w = ((digits < m) ? m : digits);
1040 p = write_block (dtp, w);
1041 if (p == NULL)
1042 return;
1044 nzero = 0;
1045 if (digits < m)
1046 nzero = m - digits;
1048 /* See if things will work. */
1050 nblank = w - (nzero + digits);
1052 if (nblank < 0)
1054 star_fill (p, w);
1055 goto done;
1059 if (!dtp->u.p.no_leading_blank)
1061 memset (p, ' ', nblank);
1062 p += nblank;
1063 memset (p, '0', nzero);
1064 p += nzero;
1065 memcpy (p, q, digits);
1067 else
1069 memset (p, '0', nzero);
1070 p += nzero;
1071 memcpy (p, q, digits);
1072 p += digits;
1073 memset (p, ' ', nblank);
1074 dtp->u.p.no_leading_blank = 0;
1077 done:
1078 return;
1081 static void
1082 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
1083 int len,
1084 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
1086 GFC_INTEGER_LARGEST n = 0;
1087 int w, m, digits, nsign, nzero, nblank;
1088 char *p;
1089 const char *q;
1090 sign_t sign;
1091 char itoa_buf[GFC_BTOA_BUF_SIZE];
1093 w = f->u.integer.w;
1094 m = f->u.integer.m;
1096 n = extract_int (source, len);
1098 /* Special case: */
1100 if (m == 0 && n == 0)
1102 if (w == 0)
1103 w = 1;
1105 p = write_block (dtp, w);
1106 if (p == NULL)
1107 return;
1109 memset (p, ' ', w);
1110 goto done;
1113 sign = calculate_sign (dtp, n < 0);
1114 if (n < 0)
1115 n = -n;
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
1123 print something. */
1125 if (w == 0)
1126 w = ((digits < m) ? m : digits) + nsign;
1128 p = write_block (dtp, w);
1129 if (p == NULL)
1130 return;
1132 nzero = 0;
1133 if (digits < m)
1134 nzero = m - digits;
1136 /* See if things will work. */
1138 nblank = w - (nsign + nzero + digits);
1140 if (nblank < 0)
1142 star_fill (p, w);
1143 goto done;
1146 memset (p, ' ', nblank);
1147 p += nblank;
1149 switch (sign)
1151 case SIGN_PLUS:
1152 *p++ = '+';
1153 break;
1154 case SIGN_MINUS:
1155 *p++ = '-';
1156 break;
1157 case SIGN_NONE:
1158 break;
1161 memset (p, '0', nzero);
1162 p += nzero;
1164 memcpy (p, q, digits);
1166 done:
1167 return;
1171 /* Convert unsigned octal to ascii. */
1173 static const char *
1174 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1176 char *p;
1178 assert (len >= GFC_OTOA_BUF_SIZE);
1180 if (n == 0)
1181 return "0";
1183 p = buffer + GFC_OTOA_BUF_SIZE - 1;
1184 *p = '\0';
1186 while (n != 0)
1188 *--p = '0' + (n & 7);
1189 n >>= 3;
1192 return p;
1196 /* Convert unsigned binary to ascii. */
1198 static const char *
1199 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1201 char *p;
1203 assert (len >= GFC_BTOA_BUF_SIZE);
1205 if (n == 0)
1206 return "0";
1208 p = buffer + GFC_BTOA_BUF_SIZE - 1;
1209 *p = '\0';
1211 while (n != 0)
1213 *--p = '0' + (n & 1);
1214 n >>= 1;
1217 return p;
1221 void
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);
1228 void
1229 write_b (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1231 write_int (dtp, f, p, len, btoa);
1235 void
1236 write_o (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1238 write_int (dtp, f, p, len, otoa);
1241 void
1242 write_z (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1244 write_int (dtp, f, p, len, xtoa);
1248 void
1249 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1251 write_float (dtp, f, p, len);
1255 void
1256 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1258 write_float (dtp, f, p, len);
1262 void
1263 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1265 write_float (dtp, f, p, len);
1269 void
1270 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1272 write_float (dtp, f, p, len);
1276 void
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. */
1285 void
1286 write_x (st_parameter_dt *dtp, int len, int nspaces)
1288 char *p;
1290 p = write_block (dtp, len);
1291 if (p == NULL)
1292 return;
1294 if (nspaces > 0)
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. */
1305 static int
1306 write_char (st_parameter_dt *dtp, char c)
1308 char *p;
1310 p = write_block (dtp, 1);
1311 if (p == NULL)
1312 return 1;
1314 *p = c;
1316 return 0;
1320 /* Write a list-directed logical value. */
1322 static void
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. */
1331 static void
1332 write_integer (st_parameter_dt *dtp, const char *source, int length)
1334 char *p;
1335 const char *q;
1336 int digits;
1337 int width;
1338 char itoa_buf[GFC_ITOA_BUF_SIZE];
1340 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1342 switch (length)
1344 case 1:
1345 width = 4;
1346 break;
1348 case 2:
1349 width = 6;
1350 break;
1352 case 4:
1353 width = 11;
1354 break;
1356 case 8:
1357 width = 20;
1358 break;
1360 default:
1361 width = 0;
1362 break;
1365 digits = strlen (q);
1367 if (width < digits)
1368 width = digits;
1369 p = write_block (dtp, width);
1370 if (p == NULL)
1371 return;
1372 if (dtp->u.p.no_leading_blank)
1374 memcpy (p, q, digits);
1375 memset (p + digits, ' ', width - digits);
1377 else
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. */
1388 static void
1389 write_character (st_parameter_dt *dtp, const char *source, int length)
1391 int i, extra;
1392 char *p, d;
1394 switch (dtp->u.p.current_unit->flags.delim)
1396 case DELIM_APOSTROPHE:
1397 d = '\'';
1398 break;
1399 case DELIM_QUOTE:
1400 d = '"';
1401 break;
1402 default:
1403 d = ' ';
1404 break;
1407 if (d == ' ')
1408 extra = 0;
1409 else
1411 extra = 2;
1413 for (i = 0; i < length; i++)
1414 if (source[i] == d)
1415 extra++;
1418 p = write_block (dtp, length + extra);
1419 if (p == NULL)
1420 return;
1422 if (d == ' ')
1423 memcpy (p, source, length);
1424 else
1426 *p++ = d;
1428 for (i = 0; i < length; i++)
1430 *p++ = source[i];
1431 if (source[i] == d)
1432 *p++ = d;
1435 *p = d;
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). */
1444 static void
1445 write_real (st_parameter_dt *dtp, const char *source, int length)
1447 fnode f ;
1448 int org_scale = dtp->u.p.scale_factor;
1449 f.format = FMT_G;
1450 dtp->u.p.scale_factor = 1;
1451 switch (length)
1453 case 4:
1454 f.u.real.w = 14;
1455 f.u.real.d = 7;
1456 f.u.real.e = 2;
1457 break;
1458 case 8:
1459 f.u.real.w = 23;
1460 f.u.real.d = 15;
1461 f.u.real.e = 3;
1462 break;
1463 case 10:
1464 f.u.real.w = 28;
1465 f.u.real.d = 19;
1466 f.u.real.e = 4;
1467 break;
1468 case 16:
1469 f.u.real.w = 43;
1470 f.u.real.d = 34;
1471 f.u.real.e = 4;
1472 break;
1473 default:
1474 internal_error (&dtp->common, "bad real kind");
1475 break;
1477 write_float (dtp, &f, source , length);
1478 dtp->u.p.scale_factor = org_scale;
1482 static void
1483 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1485 if (write_char (dtp, '('))
1486 return;
1487 write_real (dtp, source, kind);
1489 if (write_char (dtp, ','))
1490 return;
1491 write_real (dtp, source + size / 2, kind);
1493 write_char (dtp, ')');
1497 /* Write the separator between items. */
1499 static void
1500 write_separator (st_parameter_dt *dtp)
1502 char *p;
1504 p = write_block (dtp, options.separator_len);
1505 if (p == NULL)
1506 return;
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
1514 with strings. */
1516 static void
1517 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1518 size_t size)
1520 if (dtp->u.p.current_unit == NULL)
1521 return;
1523 if (dtp->u.p.first_item)
1525 dtp->u.p.first_item = 0;
1526 write_char (dtp, ' ');
1528 else
1530 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1531 dtp->u.p.current_unit->flags.delim != DELIM_NONE)
1532 write_separator (dtp);
1535 switch (type)
1537 case BT_INTEGER:
1538 write_integer (dtp, p, kind);
1539 break;
1540 case BT_LOGICAL:
1541 write_logical (dtp, p, kind);
1542 break;
1543 case BT_CHARACTER:
1544 write_character (dtp, p, kind);
1545 break;
1546 case BT_REAL:
1547 write_real (dtp, p, kind);
1548 break;
1549 case BT_COMPLEX:
1550 write_complex (dtp, p, kind, size);
1551 break;
1552 default:
1553 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1556 dtp->u.p.char_flag = (type == BT_CHARACTER);
1560 void
1561 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1562 size_t size, size_t nelems)
1564 size_t elem;
1565 char *tmp;
1567 tmp = (char *) p;
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);
1577 /* NAMELIST OUTPUT
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
1585 component.
1586 base_name = the full name for a derived type, including qualifiers
1587 if any.
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
1593 the list. */
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)
1604 int rep_ctr;
1605 int num;
1606 int nml_carry;
1607 index_type len;
1608 index_type obj_size;
1609 index_type nelem;
1610 index_type dim_i;
1611 index_type clen;
1612 index_type elem_ctr;
1613 index_type obj_name_len;
1614 void * p ;
1615 char cup;
1616 char * obj_name;
1617 char * ext_name;
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;
1623 size_t tot_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)
1630 #ifdef HAVE_CRLF
1631 write_character (dtp, "\r\n ", 3);
1632 #else
1633 write_character (dtp, "\n ", 2);
1634 #endif
1635 len = 0;
1636 if (base)
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. */
1655 num = 1;
1657 len = obj->len;
1659 switch (obj->type)
1662 case GFC_DTYPE_REAL:
1663 obj_size = size_from_real_kind (len);
1664 break;
1666 case GFC_DTYPE_COMPLEX:
1667 obj_size = size_from_complex_kind (len);
1668 break;
1670 case GFC_DTYPE_CHARACTER:
1671 obj_size = obj->string_length;
1672 break;
1674 default:
1675 obj_size = len;
1678 if (obj->var_rank)
1679 obj_size = obj->size;
1681 /* Set the index vector and count the number of elements. */
1683 nelem = 1;
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. */
1692 rep_ctr = 1;
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);
1701 p += offset;
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 ))
1709 rep_ctr++;
1712 /* Execute a repeated output. Note the flag no_leading_blank that
1713 is used in the functions used to output the intrinsic types. */
1715 else
1717 if (rep_ctr > 1)
1719 sprintf(rep_buff, " %d*", rep_ctr);
1720 write_character (dtp, rep_buff, strlen (rep_buff));
1721 dtp->u.p.no_leading_blank = 1;
1723 num++;
1725 /* Output the data, if an intrinsic type, or recurse into this
1726 routine to treat derived types. */
1728 switch (obj->type)
1731 case GFC_DTYPE_INTEGER:
1732 write_integer (dtp, p, len);
1733 break;
1735 case GFC_DTYPE_LOGICAL:
1736 write_logical (dtp, p, len);
1737 break;
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);
1745 break;
1747 case GFC_DTYPE_REAL:
1748 write_real (dtp, p, len);
1749 break;
1751 case GFC_DTYPE_COMPLEX:
1752 dtp->u.p.no_leading_blank = 0;
1753 num++;
1754 write_complex (dtp, p, len, obj_size);
1755 break;
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
1762 nml_write_obj.
1763 obj_name = the derived type name with no qualifiers but %
1764 appended. This is used to identify the
1765 components. */
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
1772 + base_var_name_len
1773 + strlen (obj->var_name)
1774 + obj->var_rank * NML_DIGITS
1775 + 1);
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++)
1787 if (!dim_i)
1789 ext_name[tot_len] = '(';
1790 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) ? ')' : ',';
1795 tot_len++;
1798 ext_name[tot_len] = '\0';
1800 /* Now obj_name. */
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);
1813 cmp = retval)
1815 retval = nml_write_obj (dtp, cmp,
1816 (index_type)(p - obj->mem_pos),
1817 obj, ext_name);
1820 free_mem (obj_name);
1821 free_mem (ext_name);
1822 goto obj_loop;
1824 default:
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);
1834 if (num > 5)
1836 num = 0;
1837 #ifdef HAVE_CRLF
1838 write_character (dtp, "\r\n ", 3);
1839 #else
1840 write_character (dtp, "\n ", 2);
1841 #endif
1843 rep_ctr = 1;
1846 /* Cycle through and increment the index vector. */
1848 obj_loop:
1850 nml_carry = 1;
1851 for (dim_i = 0; nml_carry && (dim_i < obj->var_rank); dim_i++)
1853 obj->ls[dim_i].idx += nml_carry ;
1854 nml_carry = 0;
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;
1858 nml_carry = 1;
1863 /* Return a pointer beyond the furthest object accessed. */
1865 return retval;
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. */
1873 void
1874 namelist_write (st_parameter_dt *dtp)
1876 namelist_info * t1, *t2, *dummy = NULL;
1877 index_type i;
1878 index_type dummy_offset = 0;
1879 char c;
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;
1887 switch (tmp_delim)
1889 case (DELIM_QUOTE):
1890 dtp->u.p.nml_delim = '"';
1891 break;
1893 case (DELIM_APOSTROPHE):
1894 dtp->u.p.nml_delim = '\'';
1895 break;
1897 default:
1898 dtp->u.p.nml_delim = '\0';
1899 break;
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;
1915 while (t1 != NULL)
1917 t2 = t1;
1918 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
1921 #ifdef HAVE_CRLF
1922 write_character (dtp, " /\r\n", 5);
1923 #else
1924 write_character (dtp, " /\n", 4);
1925 #endif
1927 /* Recover the original delimiter. */
1929 dtp->u.p.current_unit->flags.delim = tmp_delim;
1932 #undef NML_DIGITS