gfortran ChangeLog
[gcc.git] / libgfortran / io / write.c
1 /* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Namelist output contibuted by Paul Thomas
4
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6
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.
11
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.)
20
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.
25
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. */
30
31 #include "config.h"
32 #include <assert.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <float.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include "libgfortran.h"
39 #include "io.h"
40
41 #define star_fill(p, n) memset(p, '*', n)
42
43
44 typedef enum
45 { SIGN_NONE, SIGN_MINUS, SIGN_PLUS }
46 sign_t;
47
48
49 static int no_leading_blank = 0 ;
50
51 void
52 write_a (fnode * f, const char *source, int len)
53 {
54 int wlen;
55 char *p;
56
57 wlen = f->u.string.length < 0 ? len : f->u.string.length;
58
59 p = write_block (wlen);
60 if (p == NULL)
61 return;
62
63 if (wlen < len)
64 memcpy (p, source, wlen);
65 else
66 {
67 memset (p, ' ', wlen - len);
68 memcpy (p + wlen - len, source, len);
69 }
70 }
71
72 static GFC_INTEGER_LARGEST
73 extract_int (const void *p, int len)
74 {
75 GFC_INTEGER_LARGEST i = 0;
76
77 if (p == NULL)
78 return i;
79
80 switch (len)
81 {
82 case 1:
83 {
84 GFC_INTEGER_1 tmp;
85 memcpy ((void *) &tmp, p, len);
86 i = tmp;
87 }
88 break;
89 case 2:
90 {
91 GFC_INTEGER_2 tmp;
92 memcpy ((void *) &tmp, p, len);
93 i = tmp;
94 }
95 break;
96 case 4:
97 {
98 GFC_INTEGER_4 tmp;
99 memcpy ((void *) &tmp, p, len);
100 i = tmp;
101 }
102 break;
103 case 8:
104 {
105 GFC_INTEGER_8 tmp;
106 memcpy ((void *) &tmp, p, len);
107 i = tmp;
108 }
109 break;
110 #ifdef HAVE_GFC_INTEGER_16
111 case 16:
112 {
113 GFC_INTEGER_16 tmp;
114 memcpy ((void *) &tmp, p, len);
115 i = tmp;
116 }
117 break;
118 #endif
119 default:
120 internal_error ("bad integer kind");
121 }
122
123 return i;
124 }
125
126 static GFC_UINTEGER_LARGEST
127 extract_uint (const void *p, int len)
128 {
129 GFC_UINTEGER_LARGEST i = 0;
130
131 if (p == NULL)
132 return i;
133
134 switch (len)
135 {
136 case 1:
137 {
138 GFC_INTEGER_1 tmp;
139 memcpy ((void *) &tmp, p, len);
140 i = (GFC_UINTEGER_1) tmp;
141 }
142 break;
143 case 2:
144 {
145 GFC_INTEGER_2 tmp;
146 memcpy ((void *) &tmp, p, len);
147 i = (GFC_UINTEGER_2) tmp;
148 }
149 break;
150 case 4:
151 {
152 GFC_INTEGER_4 tmp;
153 memcpy ((void *) &tmp, p, len);
154 i = (GFC_UINTEGER_4) tmp;
155 }
156 break;
157 case 8:
158 {
159 GFC_INTEGER_8 tmp;
160 memcpy ((void *) &tmp, p, len);
161 i = (GFC_UINTEGER_8) tmp;
162 }
163 break;
164 #ifdef HAVE_GFC_INTEGER_16
165 case 16:
166 {
167 GFC_INTEGER_16 tmp;
168 memcpy ((void *) &tmp, p, len);
169 i = (GFC_UINTEGER_16) tmp;
170 }
171 break;
172 #endif
173 default:
174 internal_error ("bad integer kind");
175 }
176
177 return i;
178 }
179
180 static GFC_REAL_LARGEST
181 extract_real (const void *p, int len)
182 {
183 GFC_REAL_LARGEST i = 0;
184 switch (len)
185 {
186 case 4:
187 {
188 GFC_REAL_4 tmp;
189 memcpy ((void *) &tmp, p, len);
190 i = tmp;
191 }
192 break;
193 case 8:
194 {
195 GFC_REAL_8 tmp;
196 memcpy ((void *) &tmp, p, len);
197 i = tmp;
198 }
199 break;
200 #ifdef HAVE_GFC_REAL_10
201 case 10:
202 {
203 GFC_REAL_10 tmp;
204 memcpy ((void *) &tmp, p, len);
205 i = tmp;
206 }
207 break;
208 #endif
209 #ifdef HAVE_GFC_REAL_16
210 case 16:
211 {
212 GFC_REAL_16 tmp;
213 memcpy ((void *) &tmp, p, len);
214 i = tmp;
215 }
216 break;
217 #endif
218 default:
219 internal_error ("bad real kind");
220 }
221 return i;
222 }
223
224
225 /* Given a flag that indicate if a value is negative or not, return a
226 sign_t that gives the sign that we need to produce. */
227
228 static sign_t
229 calculate_sign (int negative_flag)
230 {
231 sign_t s = SIGN_NONE;
232
233 if (negative_flag)
234 s = SIGN_MINUS;
235 else
236 switch (g.sign_status)
237 {
238 case SIGN_SP:
239 s = SIGN_PLUS;
240 break;
241 case SIGN_SS:
242 s = SIGN_NONE;
243 break;
244 case SIGN_S:
245 s = options.optional_plus ? SIGN_PLUS : SIGN_NONE;
246 break;
247 }
248
249 return s;
250 }
251
252
253 /* Returns the value of 10**d. */
254
255 static GFC_REAL_LARGEST
256 calculate_exp (int d)
257 {
258 int i;
259 GFC_REAL_LARGEST r = 1.0;
260
261 for (i = 0; i< (d >= 0 ? d : -d); i++)
262 r *= 10;
263
264 r = (d >= 0) ? r : 1.0 / r;
265
266 return r;
267 }
268
269
270 /* Generate corresponding I/O format for FMT_G output.
271 The rules to translate FMT_G to FMT_E or FMT_F from DEC fortran
272 LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
273
274 Data Magnitude Equivalent Conversion
275 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
276 m = 0 F(w-n).(d-1), n' '
277 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
278 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
279 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
280 ................ ..........
281 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
282 m >= 10**d-0.5 Ew.d[Ee]
283
284 notes: for Gw.d , n' ' means 4 blanks
285 for Gw.dEe, n' ' means e+2 blanks */
286
287 static fnode *
288 calculate_G_format (fnode *f, GFC_REAL_LARGEST value, int *num_blank)
289 {
290 int e = f->u.real.e;
291 int d = f->u.real.d;
292 int w = f->u.real.w;
293 fnode *newf;
294 GFC_REAL_LARGEST m, exp_d;
295 int low, high, mid;
296 int ubound, lbound;
297
298 newf = get_mem (sizeof (fnode));
299
300 /* Absolute value. */
301 m = (value > 0.0) ? value : -value;
302
303 /* In case of the two data magnitude ranges,
304 generate E editing, Ew.d[Ee]. */
305 exp_d = calculate_exp (d);
306 if ((m > 0.0 && m < 0.1 - 0.05 / exp_d) || (m >= exp_d - 0.5 ))
307 {
308 newf->format = FMT_E;
309 newf->u.real.w = w;
310 newf->u.real.d = d;
311 newf->u.real.e = e;
312 *num_blank = 0;
313 return newf;
314 }
315
316 /* Use binary search to find the data magnitude range. */
317 mid = 0;
318 low = 0;
319 high = d + 1;
320 lbound = 0;
321 ubound = d + 1;
322
323 while (low <= high)
324 {
325 GFC_REAL_LARGEST temp;
326 mid = (low + high) / 2;
327
328 /* 0.1 * 10**mid - 0.5 * 10**(mid-d-1) */
329 temp = 0.1 * calculate_exp (mid) - 0.5 * calculate_exp (mid - d - 1);
330
331 if (m < temp)
332 {
333 ubound = mid;
334 if (ubound == lbound + 1)
335 break;
336 high = mid - 1;
337 }
338 else if (m > temp)
339 {
340 lbound = mid;
341 if (ubound == lbound + 1)
342 {
343 mid ++;
344 break;
345 }
346 low = mid + 1;
347 }
348 else
349 break;
350 }
351
352 /* Pad with blanks where the exponent would be. */
353 if (e < 0)
354 *num_blank = 4;
355 else
356 *num_blank = e + 2;
357
358 /* Generate the F editing. F(w-n).(-(mid-d-1)), n' '. */
359 newf->format = FMT_F;
360 newf->u.real.w = f->u.real.w - *num_blank;
361
362 /* Special case. */
363 if (m == 0.0)
364 newf->u.real.d = d - 1;
365 else
366 newf->u.real.d = - (mid - d - 1);
367
368 /* For F editing, the scale factor is ignored. */
369 g.scale_factor = 0;
370 return newf;
371 }
372
373
374 /* Output a real number according to its format which is FMT_G free. */
375
376 static void
377 output_float (fnode *f, GFC_REAL_LARGEST value)
378 {
379 /* This must be large enough to accurately hold any value. */
380 char buffer[32];
381 char *out;
382 char *digits;
383 int e;
384 char expchar;
385 format_token ft;
386 int w;
387 int d;
388 int edigits;
389 int ndigits;
390 /* Number of digits before the decimal point. */
391 int nbefore;
392 /* Number of zeros after the decimal point. */
393 int nzero;
394 /* Number of digits after the decimal point. */
395 int nafter;
396 /* Number of zeros after the decimal point, whatever the precision. */
397 int nzero_real;
398 int leadzero;
399 int nblanks;
400 int i;
401 sign_t sign;
402 double abslog;
403
404 ft = f->format;
405 w = f->u.real.w;
406 d = f->u.real.d;
407
408 nzero_real = -1;
409
410
411 /* We should always know the field width and precision. */
412 if (d < 0)
413 internal_error ("Unspecified precision");
414
415 /* Use sprintf to print the number in the format +D.DDDDe+ddd
416 For an N digit exponent, this gives us (32-6)-N digits after the
417 decimal point, plus another one before the decimal point. */
418 sign = calculate_sign (value < 0.0);
419 if (value < 0)
420 value = -value;
421
422 /* Printf always prints at least two exponent digits. */
423 if (value == 0)
424 edigits = 2;
425 else
426 {
427 #if defined(HAVE_GFC_REAL_10) || defined(HAVE_GFC_REAL_16)
428 abslog = fabs((double) log10l(value));
429 #else
430 abslog = fabs(log10(value));
431 #endif
432 if (abslog < 100)
433 edigits = 2;
434 else
435 edigits = 1 + (int) log10(abslog);
436 }
437
438 if (ft == FMT_F || ft == FMT_EN
439 || ((ft == FMT_D || ft == FMT_E) && g.scale_factor != 0))
440 {
441 /* Always convert at full precision to avoid double rounding. */
442 ndigits = 27 - edigits;
443 }
444 else
445 {
446 /* We know the number of digits, so can let printf do the rounding
447 for us. */
448 if (ft == FMT_ES)
449 ndigits = d + 1;
450 else
451 ndigits = d;
452 if (ndigits > 27 - edigits)
453 ndigits = 27 - edigits;
454 }
455
456 /* # The result will always contain a decimal point, even if no
457 * digits follow it
458 *
459 * - The converted value is to be left adjusted on the field boundary
460 *
461 * + A sign (+ or -) always be placed before a number
462 *
463 * 31 minimum field width
464 *
465 * * (ndigits-1) is used as the precision
466 *
467 * e format: [-]d.ddde±dd where there is one digit before the
468 * decimal-point character and the number of digits after it is
469 * equal to the precision. The exponent always contains at least two
470 * digits; if the value is zero, the exponent is 00.
471 */
472 sprintf (buffer, "%+-#31.*" GFC_REAL_LARGEST_FORMAT "e",
473 ndigits - 1, value);
474
475 /* Check the resulting string has punctuation in the correct places. */
476 if (buffer[2] != '.' || buffer[ndigits + 2] != 'e')
477 internal_error ("printf is broken");
478
479 /* Read the exponent back in. */
480 e = atoi (&buffer[ndigits + 3]) + 1;
481
482 /* Make sure zero comes out as 0.0e0. */
483 if (value == 0.0)
484 e = 0;
485
486 /* Normalize the fractional component. */
487 buffer[2] = buffer[1];
488 digits = &buffer[2];
489
490 /* Figure out where to place the decimal point. */
491 switch (ft)
492 {
493 case FMT_F:
494 nbefore = e + g.scale_factor;
495 if (nbefore < 0)
496 {
497 nzero = -nbefore;
498 nzero_real = nzero;
499 if (nzero > d)
500 nzero = d;
501 nafter = d - nzero;
502 nbefore = 0;
503 }
504 else
505 {
506 nzero = 0;
507 nafter = d;
508 }
509 expchar = 0;
510 break;
511
512 case FMT_E:
513 case FMT_D:
514 i = g.scale_factor;
515 if (value != 0.0)
516 e -= i;
517 if (i < 0)
518 {
519 nbefore = 0;
520 nzero = -i;
521 nafter = d + i;
522 }
523 else if (i > 0)
524 {
525 nbefore = i;
526 nzero = 0;
527 nafter = (d - i) + 1;
528 }
529 else /* i == 0 */
530 {
531 nbefore = 0;
532 nzero = 0;
533 nafter = d;
534 }
535
536 if (ft == FMT_E)
537 expchar = 'E';
538 else
539 expchar = 'D';
540 break;
541
542 case FMT_EN:
543 /* The exponent must be a multiple of three, with 1-3 digits before
544 the decimal point. */
545 if (value != 0.0)
546 e--;
547 if (e >= 0)
548 nbefore = e % 3;
549 else
550 {
551 nbefore = (-e) % 3;
552 if (nbefore != 0)
553 nbefore = 3 - nbefore;
554 }
555 e -= nbefore;
556 nbefore++;
557 nzero = 0;
558 nafter = d;
559 expchar = 'E';
560 break;
561
562 case FMT_ES:
563 if (value != 0.0)
564 e--;
565 nbefore = 1;
566 nzero = 0;
567 nafter = d;
568 expchar = 'E';
569 break;
570
571 default:
572 /* Should never happen. */
573 internal_error ("Unexpected format token");
574 }
575
576 /* Round the value. */
577 if (nbefore + nafter == 0)
578 {
579 ndigits = 0;
580 if (nzero_real == d && digits[0] >= '5')
581 {
582 /* We rounded to zero but shouldn't have */
583 nzero--;
584 nafter = 1;
585 digits[0] = '1';
586 ndigits = 1;
587 }
588 }
589 else if (nbefore + nafter < ndigits)
590 {
591 ndigits = nbefore + nafter;
592 i = ndigits;
593 if (digits[i] >= '5')
594 {
595 /* Propagate the carry. */
596 for (i--; i >= 0; i--)
597 {
598 if (digits[i] != '9')
599 {
600 digits[i]++;
601 break;
602 }
603 digits[i] = '0';
604 }
605
606 if (i < 0)
607 {
608 /* The carry overflowed. Fortunately we have some spare space
609 at the start of the buffer. We may discard some digits, but
610 this is ok because we already know they are zero. */
611 digits--;
612 digits[0] = '1';
613 if (ft == FMT_F)
614 {
615 if (nzero > 0)
616 {
617 nzero--;
618 nafter++;
619 }
620 else
621 nbefore++;
622 }
623 else if (ft == FMT_EN)
624 {
625 nbefore++;
626 if (nbefore == 4)
627 {
628 nbefore = 1;
629 e += 3;
630 }
631 }
632 else
633 e++;
634 }
635 }
636 }
637
638 /* Calculate the format of the exponent field. */
639 if (expchar)
640 {
641 edigits = 1;
642 for (i = abs (e); i >= 10; i /= 10)
643 edigits++;
644
645 if (f->u.real.e < 0)
646 {
647 /* Width not specified. Must be no more than 3 digits. */
648 if (e > 999 || e < -999)
649 edigits = -1;
650 else
651 {
652 edigits = 4;
653 if (e > 99 || e < -99)
654 expchar = ' ';
655 }
656 }
657 else
658 {
659 /* Exponent width specified, check it is wide enough. */
660 if (edigits > f->u.real.e)
661 edigits = -1;
662 else
663 edigits = f->u.real.e + 2;
664 }
665 }
666 else
667 edigits = 0;
668
669 /* Pick a field size if none was specified. */
670 if (w <= 0)
671 w = nbefore + nzero + nafter + (sign != SIGN_NONE ? 2 : 1);
672
673 /* Create the ouput buffer. */
674 out = write_block (w);
675 if (out == NULL)
676 return;
677
678 /* Zero values always output as positive, even if the value was negative
679 before rounding. */
680 for (i = 0; i < ndigits; i++)
681 {
682 if (digits[i] != '0')
683 break;
684 }
685 if (i == ndigits)
686 sign = calculate_sign (0);
687
688 /* Work out how much padding is needed. */
689 nblanks = w - (nbefore + nzero + nafter + edigits + 1);
690 if (sign != SIGN_NONE)
691 nblanks--;
692
693 /* Check the value fits in the specified field width. */
694 if (nblanks < 0 || edigits == -1)
695 {
696 star_fill (out, w);
697 return;
698 }
699
700 /* See if we have space for a zero before the decimal point. */
701 if (nbefore == 0 && nblanks > 0)
702 {
703 leadzero = 1;
704 nblanks--;
705 }
706 else
707 leadzero = 0;
708
709 /* Pad to full field width. */
710
711
712 if ( ( nblanks > 0 ) && !no_leading_blank )
713 {
714 memset (out, ' ', nblanks);
715 out += nblanks;
716 }
717
718 /* Output the initial sign (if any). */
719 if (sign == SIGN_PLUS)
720 *(out++) = '+';
721 else if (sign == SIGN_MINUS)
722 *(out++) = '-';
723
724 /* Output an optional leading zero. */
725 if (leadzero)
726 *(out++) = '0';
727
728 /* Output the part before the decimal point, padding with zeros. */
729 if (nbefore > 0)
730 {
731 if (nbefore > ndigits)
732 i = ndigits;
733 else
734 i = nbefore;
735
736 memcpy (out, digits, i);
737 while (i < nbefore)
738 out[i++] = '0';
739
740 digits += i;
741 ndigits -= i;
742 out += nbefore;
743 }
744 /* Output the decimal point. */
745 *(out++) = '.';
746
747 /* Output leading zeros after the decimal point. */
748 if (nzero > 0)
749 {
750 for (i = 0; i < nzero; i++)
751 *(out++) = '0';
752 }
753
754 /* Output digits after the decimal point, padding with zeros. */
755 if (nafter > 0)
756 {
757 if (nafter > ndigits)
758 i = ndigits;
759 else
760 i = nafter;
761
762 memcpy (out, digits, i);
763 while (i < nafter)
764 out[i++] = '0';
765
766 digits += i;
767 ndigits -= i;
768 out += nafter;
769 }
770
771 /* Output the exponent. */
772 if (expchar)
773 {
774 if (expchar != ' ')
775 {
776 *(out++) = expchar;
777 edigits--;
778 }
779 #if HAVE_SNPRINTF
780 snprintf (buffer, 32, "%+0*d", edigits, e);
781 #else
782 sprintf (buffer, "%+0*d", edigits, e);
783 #endif
784 memcpy (out, buffer, edigits);
785 }
786
787 if ( no_leading_blank )
788 {
789 out += edigits;
790 memset( out , ' ' , nblanks );
791 no_leading_blank = 0;
792 }
793 }
794
795
796 void
797 write_l (fnode * f, char *source, int len)
798 {
799 char *p;
800 GFC_INTEGER_LARGEST n;
801
802 p = write_block (f->u.w);
803 if (p == NULL)
804 return;
805
806 memset (p, ' ', f->u.w - 1);
807 n = extract_int (source, len);
808 p[f->u.w - 1] = (n) ? 'T' : 'F';
809 }
810
811 /* Output a real number according to its format. */
812
813 static void
814 write_float (fnode *f, const char *source, int len)
815 {
816 GFC_REAL_LARGEST n;
817 int nb =0, res, save_scale_factor;
818 char * p, fin;
819 fnode *f2 = NULL;
820
821 n = extract_real (source, len);
822
823 if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z)
824 {
825 res = isfinite (n);
826 if (res == 0)
827 {
828 nb = f->u.real.w;
829
830 /* If the field width is zero, the processor must select a width
831 not zero. 4 is chosen to allow output of '-Inf' or '+Inf' */
832
833 if (nb == 0) nb = 4;
834 p = write_block (nb);
835 if (p == NULL)
836 return;
837 if (nb < 3)
838 {
839 memset (p, '*',nb);
840 return;
841 }
842
843 memset(p, ' ', nb);
844 res = !isnan (n);
845 if (res != 0)
846 {
847 if (signbit(n))
848 {
849
850 /* If the sign is negative and the width is 3, there is
851 insufficient room to output '-Inf', so output asterisks */
852
853 if (nb == 3)
854 {
855 memset (p, '*',nb);
856 return;
857 }
858
859 /* The negative sign is mandatory */
860
861 fin = '-';
862 }
863 else
864
865 /* The positive sign is optional, but we output it for
866 consistency */
867
868 fin = '+';
869
870 if (nb > 8)
871
872 /* We have room, so output 'Infinity' */
873
874 memcpy(p + nb - 8, "Infinity", 8);
875 else
876
877 /* For the case of width equals 8, there is not enough room
878 for the sign and 'Infinity' so we go with 'Inf' */
879
880 memcpy(p + nb - 3, "Inf", 3);
881 if (nb < 9 && nb > 3)
882 p[nb - 4] = fin; /* Put the sign in front of Inf */
883 else if (nb > 8)
884 p[nb - 9] = fin; /* Put the sign in front of Infinity */
885 }
886 else
887 memcpy(p + nb - 3, "NaN", 3);
888 return;
889 }
890 }
891
892 if (f->format != FMT_G)
893 {
894 output_float (f, n);
895 }
896 else
897 {
898 save_scale_factor = g.scale_factor;
899 f2 = calculate_G_format(f, n, &nb);
900 output_float (f2, n);
901 g.scale_factor = save_scale_factor;
902 if (f2 != NULL)
903 free_mem(f2);
904
905 if (nb > 0)
906 {
907 p = write_block (nb);
908 if (p == NULL)
909 return;
910 memset (p, ' ', nb);
911 }
912 }
913 }
914
915
916 static void
917 write_int (fnode *f, const char *source, int len,
918 const char *(*conv) (GFC_UINTEGER_LARGEST, char *, size_t))
919 {
920 GFC_UINTEGER_LARGEST n = 0;
921 int w, m, digits, nzero, nblank;
922 char *p;
923 const char *q;
924 char itoa_buf[GFC_BTOA_BUF_SIZE];
925
926 w = f->u.integer.w;
927 m = f->u.integer.m;
928
929 n = extract_uint (source, len);
930
931 /* Special case: */
932
933 if (m == 0 && n == 0)
934 {
935 if (w == 0)
936 w = 1;
937
938 p = write_block (w);
939 if (p == NULL)
940 return;
941
942 memset (p, ' ', w);
943 goto done;
944 }
945
946 q = conv (n, itoa_buf, sizeof (itoa_buf));
947 digits = strlen (q);
948
949 /* Select a width if none was specified. The idea here is to always
950 print something. */
951
952 if (w == 0)
953 w = ((digits < m) ? m : digits);
954
955 p = write_block (w);
956 if (p == NULL)
957 return;
958
959 nzero = 0;
960 if (digits < m)
961 nzero = m - digits;
962
963 /* See if things will work. */
964
965 nblank = w - (nzero + digits);
966
967 if (nblank < 0)
968 {
969 star_fill (p, w);
970 goto done;
971 }
972
973
974 if (!no_leading_blank)
975 {
976 memset (p, ' ', nblank);
977 p += nblank;
978 memset (p, '0', nzero);
979 p += nzero;
980 memcpy (p, q, digits);
981 }
982 else
983 {
984 memset (p, '0', nzero);
985 p += nzero;
986 memcpy (p, q, digits);
987 p += digits;
988 memset (p, ' ', nblank);
989 no_leading_blank = 0;
990 }
991
992 done:
993 return;
994 }
995
996 static void
997 write_decimal (fnode *f, const char *source, int len,
998 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
999 {
1000 GFC_INTEGER_LARGEST n = 0;
1001 int w, m, digits, nsign, nzero, nblank;
1002 char *p;
1003 const char *q;
1004 sign_t sign;
1005 char itoa_buf[GFC_BTOA_BUF_SIZE];
1006
1007 w = f->u.integer.w;
1008 m = f->u.integer.m;
1009
1010 n = extract_int (source, len);
1011
1012 /* Special case: */
1013
1014 if (m == 0 && n == 0)
1015 {
1016 if (w == 0)
1017 w = 1;
1018
1019 p = write_block (w);
1020 if (p == NULL)
1021 return;
1022
1023 memset (p, ' ', w);
1024 goto done;
1025 }
1026
1027 sign = calculate_sign (n < 0);
1028 if (n < 0)
1029 n = -n;
1030
1031 nsign = sign == SIGN_NONE ? 0 : 1;
1032 q = conv (n, itoa_buf, sizeof (itoa_buf));
1033
1034 digits = strlen (q);
1035
1036 /* Select a width if none was specified. The idea here is to always
1037 print something. */
1038
1039 if (w == 0)
1040 w = ((digits < m) ? m : digits) + nsign;
1041
1042 p = write_block (w);
1043 if (p == NULL)
1044 return;
1045
1046 nzero = 0;
1047 if (digits < m)
1048 nzero = m - digits;
1049
1050 /* See if things will work. */
1051
1052 nblank = w - (nsign + nzero + digits);
1053
1054 if (nblank < 0)
1055 {
1056 star_fill (p, w);
1057 goto done;
1058 }
1059
1060 memset (p, ' ', nblank);
1061 p += nblank;
1062
1063 switch (sign)
1064 {
1065 case SIGN_PLUS:
1066 *p++ = '+';
1067 break;
1068 case SIGN_MINUS:
1069 *p++ = '-';
1070 break;
1071 case SIGN_NONE:
1072 break;
1073 }
1074
1075 memset (p, '0', nzero);
1076 p += nzero;
1077
1078 memcpy (p, q, digits);
1079
1080 done:
1081 return;
1082 }
1083
1084
1085 /* Convert unsigned octal to ascii. */
1086
1087 static const char *
1088 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1089 {
1090 char *p;
1091
1092 assert (len >= GFC_OTOA_BUF_SIZE);
1093
1094 if (n == 0)
1095 return "0";
1096
1097 p = buffer + GFC_OTOA_BUF_SIZE - 1;
1098 *p = '\0';
1099
1100 while (n != 0)
1101 {
1102 *--p = '0' + (n & 7);
1103 n >>= 3;
1104 }
1105
1106 return p;
1107 }
1108
1109
1110 /* Convert unsigned binary to ascii. */
1111
1112 static const char *
1113 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1114 {
1115 char *p;
1116
1117 assert (len >= GFC_BTOA_BUF_SIZE);
1118
1119 if (n == 0)
1120 return "0";
1121
1122 p = buffer + GFC_BTOA_BUF_SIZE - 1;
1123 *p = '\0';
1124
1125 while (n != 0)
1126 {
1127 *--p = '0' + (n & 1);
1128 n >>= 1;
1129 }
1130
1131 return p;
1132 }
1133
1134
1135 void
1136 write_i (fnode * f, const char *p, int len)
1137 {
1138 write_decimal (f, p, len, (void *) gfc_itoa);
1139 }
1140
1141
1142 void
1143 write_b (fnode * f, const char *p, int len)
1144 {
1145 write_int (f, p, len, btoa);
1146 }
1147
1148
1149 void
1150 write_o (fnode * f, const char *p, int len)
1151 {
1152 write_int (f, p, len, otoa);
1153 }
1154
1155 void
1156 write_z (fnode * f, const char *p, int len)
1157 {
1158 write_int (f, p, len, xtoa);
1159 }
1160
1161
1162 void
1163 write_d (fnode *f, const char *p, int len)
1164 {
1165 write_float (f, p, len);
1166 }
1167
1168
1169 void
1170 write_e (fnode *f, const char *p, int len)
1171 {
1172 write_float (f, p, len);
1173 }
1174
1175
1176 void
1177 write_f (fnode *f, const char *p, int len)
1178 {
1179 write_float (f, p, len);
1180 }
1181
1182
1183 void
1184 write_en (fnode *f, const char *p, int len)
1185 {
1186 write_float (f, p, len);
1187 }
1188
1189
1190 void
1191 write_es (fnode *f, const char *p, int len)
1192 {
1193 write_float (f, p, len);
1194 }
1195
1196
1197 /* Take care of the X/TR descriptor. */
1198
1199 void
1200 write_x (int len, int nspaces)
1201 {
1202 char *p;
1203
1204 p = write_block (len);
1205 if (p == NULL)
1206 return;
1207
1208 if (nspaces > 0)
1209 memset (&p[len - nspaces], ' ', nspaces);
1210 }
1211
1212
1213 /* List-directed writing. */
1214
1215
1216 /* Write a single character to the output. Returns nonzero if
1217 something goes wrong. */
1218
1219 static int
1220 write_char (char c)
1221 {
1222 char *p;
1223
1224 p = write_block (1);
1225 if (p == NULL)
1226 return 1;
1227
1228 *p = c;
1229
1230 return 0;
1231 }
1232
1233
1234 /* Write a list-directed logical value. */
1235
1236 static void
1237 write_logical (const char *source, int length)
1238 {
1239 write_char (extract_int (source, length) ? 'T' : 'F');
1240 }
1241
1242
1243 /* Write a list-directed integer value. */
1244
1245 static void
1246 write_integer (const char *source, int length)
1247 {
1248 char *p;
1249 const char *q;
1250 int digits;
1251 int width;
1252 char itoa_buf[GFC_ITOA_BUF_SIZE];
1253
1254 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1255
1256 switch (length)
1257 {
1258 case 1:
1259 width = 4;
1260 break;
1261
1262 case 2:
1263 width = 6;
1264 break;
1265
1266 case 4:
1267 width = 11;
1268 break;
1269
1270 case 8:
1271 width = 20;
1272 break;
1273
1274 default:
1275 width = 0;
1276 break;
1277 }
1278
1279 digits = strlen (q);
1280
1281 if(width < digits )
1282 width = digits ;
1283 p = write_block (width) ;
1284 if (p == NULL)
1285 return;
1286 if (no_leading_blank)
1287 {
1288 memcpy (p, q, digits);
1289 memset(p + digits ,' ', width - digits) ;
1290 }
1291 else
1292 {
1293 memset(p ,' ', width - digits) ;
1294 memcpy (p + width - digits, q, digits);
1295 }
1296 }
1297
1298
1299 /* Write a list-directed string. We have to worry about delimiting
1300 the strings if the file has been opened in that mode. */
1301
1302 static void
1303 write_character (const char *source, int length)
1304 {
1305 int i, extra;
1306 char *p, d;
1307
1308 switch (current_unit->flags.delim)
1309 {
1310 case DELIM_APOSTROPHE:
1311 d = '\'';
1312 break;
1313 case DELIM_QUOTE:
1314 d = '"';
1315 break;
1316 default:
1317 d = ' ';
1318 break;
1319 }
1320
1321 if (d == ' ')
1322 extra = 0;
1323 else
1324 {
1325 extra = 2;
1326
1327 for (i = 0; i < length; i++)
1328 if (source[i] == d)
1329 extra++;
1330 }
1331
1332 p = write_block (length + extra);
1333 if (p == NULL)
1334 return;
1335
1336 if (d == ' ')
1337 memcpy (p, source, length);
1338 else
1339 {
1340 *p++ = d;
1341
1342 for (i = 0; i < length; i++)
1343 {
1344 *p++ = source[i];
1345 if (source[i] == d)
1346 *p++ = d;
1347 }
1348
1349 *p = d;
1350 }
1351 }
1352
1353
1354 /* Output a real number with default format.
1355 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
1356 1PG24.15E4 for REAL(10) and 1PG40.31E4 for REAL(16). */
1357
1358 static void
1359 write_real (const char *source, int length)
1360 {
1361 fnode f ;
1362 int org_scale = g.scale_factor;
1363 f.format = FMT_G;
1364 g.scale_factor = 1;
1365 switch (length)
1366 {
1367 case 4:
1368 f.u.real.w = 14;
1369 f.u.real.d = 7;
1370 f.u.real.e = 2;
1371 break;
1372 case 8:
1373 f.u.real.w = 23;
1374 f.u.real.d = 15;
1375 f.u.real.e = 3;
1376 break;
1377 case 10:
1378 f.u.real.w = 24;
1379 f.u.real.d = 15;
1380 f.u.real.e = 4;
1381 break;
1382 case 16:
1383 f.u.real.w = 40;
1384 f.u.real.d = 31;
1385 f.u.real.e = 4;
1386 break;
1387 default:
1388 internal_error ("bad real kind");
1389 break;
1390 }
1391 write_float (&f, source , length);
1392 g.scale_factor = org_scale;
1393 }
1394
1395
1396 static void
1397 write_complex (const char *source, int kind, size_t size)
1398 {
1399 if (write_char ('('))
1400 return;
1401 write_real (source, kind);
1402
1403 if (write_char (','))
1404 return;
1405 write_real (source + size / 2, kind);
1406
1407 write_char (')');
1408 }
1409
1410
1411 /* Write the separator between items. */
1412
1413 static void
1414 write_separator (void)
1415 {
1416 char *p;
1417
1418 p = write_block (options.separator_len);
1419 if (p == NULL)
1420 return;
1421
1422 memcpy (p, options.separator, options.separator_len);
1423 }
1424
1425
1426 /* Write an item with list formatting.
1427 TODO: handle skipping to the next record correctly, particularly
1428 with strings. */
1429
1430 static void
1431 list_formatted_write_scalar (bt type, void *p, int kind, size_t size)
1432 {
1433 static int char_flag;
1434
1435 if (current_unit == NULL)
1436 return;
1437
1438 if (g.first_item)
1439 {
1440 g.first_item = 0;
1441 char_flag = 0;
1442 write_char (' ');
1443 }
1444 else
1445 {
1446 if (type != BT_CHARACTER || !char_flag ||
1447 current_unit->flags.delim != DELIM_NONE)
1448 write_separator ();
1449 }
1450
1451 switch (type)
1452 {
1453 case BT_INTEGER:
1454 write_integer (p, kind);
1455 break;
1456 case BT_LOGICAL:
1457 write_logical (p, kind);
1458 break;
1459 case BT_CHARACTER:
1460 write_character (p, kind);
1461 break;
1462 case BT_REAL:
1463 write_real (p, kind);
1464 break;
1465 case BT_COMPLEX:
1466 write_complex (p, kind, size);
1467 break;
1468 default:
1469 internal_error ("list_formatted_write(): Bad type");
1470 }
1471
1472 char_flag = (type == BT_CHARACTER);
1473 }
1474
1475
1476 void
1477 list_formatted_write (bt type, void *p, int kind, size_t size, size_t nelems)
1478 {
1479 size_t elem;
1480 char *tmp;
1481
1482 tmp = (char *) p;
1483
1484 /* Big loop over all the elements. */
1485 for (elem = 0; elem < nelems; elem++)
1486 {
1487 g.item_count++;
1488 list_formatted_write_scalar (type, tmp + size*elem, kind, size);
1489 }
1490 }
1491
1492 /* NAMELIST OUTPUT
1493
1494 nml_write_obj writes a namelist object to the output stream. It is called
1495 recursively for derived type components:
1496 obj = is the namelist_info for the current object.
1497 offset = the offset relative to the address held by the object for
1498 derived type arrays.
1499 base = is the namelist_info of the derived type, when obj is a
1500 component.
1501 base_name = the full name for a derived type, including qualifiers
1502 if any.
1503 The returned value is a pointer to the object beyond the last one
1504 accessed, including nested derived types. Notice that the namelist is
1505 a linear linked list of objects, including derived types and their
1506 components. A tree, of sorts, is implied by the compound names of
1507 the derived type components and this is how this function recurses through
1508 the list. */
1509
1510 /* A generous estimate of the number of characters needed to print
1511 repeat counts and indices, including commas, asterices and brackets. */
1512
1513 #define NML_DIGITS 20
1514
1515 /* Stores the delimiter to be used for character objects. */
1516
1517 static const char * nml_delim;
1518
1519 static namelist_info *
1520 nml_write_obj (namelist_info * obj, index_type offset,
1521 namelist_info * base, char * base_name)
1522 {
1523 int rep_ctr;
1524 int num;
1525 int nml_carry;
1526 index_type len;
1527 index_type obj_size;
1528 index_type nelem;
1529 index_type dim_i;
1530 index_type clen;
1531 index_type elem_ctr;
1532 index_type obj_name_len;
1533 void * p ;
1534 char cup;
1535 char * obj_name;
1536 char * ext_name;
1537 char rep_buff[NML_DIGITS];
1538 namelist_info * cmp;
1539 namelist_info * retval = obj->next;
1540
1541 /* Write namelist variable names in upper case. If a derived type,
1542 nothing is output. If a component, base and base_name are set. */
1543
1544 if (obj->type != GFC_DTYPE_DERIVED)
1545 {
1546 write_character ("\n ", 2);
1547 len = 0;
1548 if (base)
1549 {
1550 len =strlen (base->var_name);
1551 for (dim_i = 0; dim_i < (index_type) strlen (base_name); dim_i++)
1552 {
1553 cup = toupper (base_name[dim_i]);
1554 write_character (&cup, 1);
1555 }
1556 }
1557 for (dim_i =len; dim_i < (index_type) strlen (obj->var_name); dim_i++)
1558 {
1559 cup = toupper (obj->var_name[dim_i]);
1560 write_character (&cup, 1);
1561 }
1562 write_character ("=", 1);
1563 }
1564
1565 /* Counts the number of data output on a line, including names. */
1566
1567 num = 1;
1568
1569 len = obj->len;
1570
1571 switch (obj->type)
1572 {
1573
1574 case GFC_DTYPE_REAL:
1575 obj_size = size_from_real_kind (len);
1576 break;
1577
1578 case GFC_DTYPE_COMPLEX:
1579 obj_size = size_from_complex_kind (len);
1580 break;
1581
1582 case GFC_DTYPE_CHARACTER:
1583 obj_size = obj->string_length;
1584 break;
1585
1586 default:
1587 obj_size = len;
1588 }
1589
1590 if (obj->var_rank)
1591 obj_size = obj->size;
1592
1593 /* Set the index vector and count the number of elements. */
1594
1595 nelem = 1;
1596 for (dim_i=0; dim_i < obj->var_rank; dim_i++)
1597 {
1598 obj->ls[dim_i].idx = obj->dim[dim_i].lbound;
1599 nelem = nelem * (obj->dim[dim_i].ubound + 1 - obj->dim[dim_i].lbound);
1600 }
1601
1602 /* Main loop to output the data held in the object. */
1603
1604 rep_ctr = 1;
1605 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
1606 {
1607
1608 /* Build the pointer to the data value. The offset is passed by
1609 recursive calls to this function for arrays of derived types.
1610 Is NULL otherwise. */
1611
1612 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
1613 p += offset;
1614
1615 /* Check for repeat counts of intrinsic types. */
1616
1617 if ((elem_ctr < (nelem - 1)) &&
1618 (obj->type != GFC_DTYPE_DERIVED) &&
1619 !memcmp (p, (void*)(p + obj_size ), obj_size ))
1620 {
1621 rep_ctr++;
1622 }
1623
1624 /* Execute a repeated output. Note the flag no_leading_blank that
1625 is used in the functions used to output the intrinsic types. */
1626
1627 else
1628 {
1629 if (rep_ctr > 1)
1630 {
1631 st_sprintf(rep_buff, " %d*", rep_ctr);
1632 write_character (rep_buff, strlen (rep_buff));
1633 no_leading_blank = 1;
1634 }
1635 num++;
1636
1637 /* Output the data, if an intrinsic type, or recurse into this
1638 routine to treat derived types. */
1639
1640 switch (obj->type)
1641 {
1642
1643 case GFC_DTYPE_INTEGER:
1644 write_integer (p, len);
1645 break;
1646
1647 case GFC_DTYPE_LOGICAL:
1648 write_logical (p, len);
1649 break;
1650
1651 case GFC_DTYPE_CHARACTER:
1652 if (nml_delim)
1653 write_character (nml_delim, 1);
1654 write_character (p, obj->string_length);
1655 if (nml_delim)
1656 write_character (nml_delim, 1);
1657 break;
1658
1659 case GFC_DTYPE_REAL:
1660 write_real (p, len);
1661 break;
1662
1663 case GFC_DTYPE_COMPLEX:
1664 no_leading_blank = 0;
1665 num++;
1666 write_complex (p, len, obj_size);
1667 break;
1668
1669 case GFC_DTYPE_DERIVED:
1670
1671 /* To treat a derived type, we need to build two strings:
1672 ext_name = the name, including qualifiers that prepends
1673 component names in the output - passed to
1674 nml_write_obj.
1675 obj_name = the derived type name with no qualifiers but %
1676 appended. This is used to identify the
1677 components. */
1678
1679 /* First ext_name => get length of all possible components */
1680
1681 ext_name = (char*)get_mem ( (base_name ? strlen (base_name) : 0)
1682 + (base ? strlen (base->var_name) : 0)
1683 + strlen (obj->var_name)
1684 + obj->var_rank * NML_DIGITS
1685 + 1);
1686
1687 strcpy(ext_name, base_name ? base_name : "");
1688 clen = base ? strlen (base->var_name) : 0;
1689 strcat (ext_name, obj->var_name + clen);
1690
1691 /* Append the qualifier. */
1692
1693 for (dim_i = 0; dim_i < obj->var_rank; dim_i++)
1694 {
1695 strcat (ext_name, dim_i ? "" : "(");
1696 clen = strlen (ext_name);
1697 st_sprintf (ext_name + clen, "%d", (int) obj->ls[dim_i].idx);
1698 strcat (ext_name, (dim_i == obj->var_rank - 1) ? ")" : ",");
1699 }
1700
1701 /* Now obj_name. */
1702
1703 obj_name_len = strlen (obj->var_name) + 1;
1704 obj_name = get_mem (obj_name_len+1);
1705 strcpy (obj_name, obj->var_name);
1706 strcat (obj_name, "%");
1707
1708 /* Now loop over the components. Update the component pointer
1709 with the return value from nml_write_obj => this loop jumps
1710 past nested derived types. */
1711
1712 for (cmp = obj->next;
1713 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
1714 cmp = retval)
1715 {
1716 retval = nml_write_obj (cmp, (index_type)(p - obj->mem_pos),
1717 obj, ext_name);
1718 }
1719
1720 free_mem (obj_name);
1721 free_mem (ext_name);
1722 goto obj_loop;
1723
1724 default:
1725 internal_error ("Bad type for namelist write");
1726 }
1727
1728 /* Reset the leading blank suppression, write a comma and, if 5
1729 values have been output, write a newline and advance to column
1730 2. Reset the repeat counter. */
1731
1732 no_leading_blank = 0;
1733 write_character (",", 1);
1734 if (num > 5)
1735 {
1736 num = 0;
1737 write_character ("\n ", 2);
1738 }
1739 rep_ctr = 1;
1740 }
1741
1742 /* Cycle through and increment the index vector. */
1743
1744 obj_loop:
1745
1746 nml_carry = 1;
1747 for (dim_i = 0; nml_carry && (dim_i < obj->var_rank); dim_i++)
1748 {
1749 obj->ls[dim_i].idx += nml_carry ;
1750 nml_carry = 0;
1751 if (obj->ls[dim_i].idx > (ssize_t)obj->dim[dim_i].ubound)
1752 {
1753 obj->ls[dim_i].idx = obj->dim[dim_i].lbound;
1754 nml_carry = 1;
1755 }
1756 }
1757 }
1758
1759 /* Return a pointer beyond the furthest object accessed. */
1760
1761 return retval;
1762 }
1763
1764 /* This is the entry function for namelist writes. It outputs the name
1765 of the namelist and iterates through the namelist by calls to
1766 nml_write_obj. The call below has dummys in the arguments used in
1767 the treatment of derived types. */
1768
1769 void
1770 namelist_write (void)
1771 {
1772 namelist_info * t1, *t2, *dummy = NULL;
1773 index_type i;
1774 index_type dummy_offset = 0;
1775 char c;
1776 char * dummy_name = NULL;
1777 unit_delim tmp_delim;
1778
1779 /* Set the delimiter for namelist output. */
1780
1781 tmp_delim = current_unit->flags.delim;
1782 current_unit->flags.delim = DELIM_NONE;
1783 switch (tmp_delim)
1784 {
1785 case (DELIM_QUOTE):
1786 nml_delim = "\"";
1787 break;
1788
1789 case (DELIM_APOSTROPHE):
1790 nml_delim = "'";
1791 break;
1792
1793 default:
1794 nml_delim = NULL;
1795 }
1796
1797 write_character ("&",1);
1798
1799 /* Write namelist name in upper case - f95 std. */
1800
1801 for (i = 0 ;i < ioparm.namelist_name_len ;i++ )
1802 {
1803 c = toupper (ioparm.namelist_name[i]);
1804 write_character (&c ,1);
1805 }
1806
1807 if (ionml != NULL)
1808 {
1809 t1 = ionml;
1810 while (t1 != NULL)
1811 {
1812 t2 = t1;
1813 t1 = nml_write_obj (t2, dummy_offset, dummy, dummy_name);
1814 }
1815 }
1816 write_character (" /\n", 4);
1817
1818 /* Recover the original delimiter. */
1819
1820 current_unit->flags.delim = tmp_delim;
1821 }
1822
1823 #undef NML_DIGITS