2016-08-31 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libgfortran / io / write.c
blob15f7158dbb764fa11b413b32a53354a852d5a6f7
1 /* Copyright (C) 2002-2016 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Namelist output contributed by Paul Thomas
4 F2003 I/O support contributed by Jerry DeLisle
6 This file is part of the GNU Fortran runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "io.h"
28 #include "fbuf.h"
29 #include "format.h"
30 #include "unix.h"
31 #include <assert.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #define star_fill(p, n) memset(p, '*', n)
38 typedef unsigned char uchar;
40 /* Helper functions for character(kind=4) internal units. These are needed
41 by write_float.def. */
43 static void
44 memcpy4 (gfc_char4_t *dest, const char *source, int k)
46 int j;
48 const char *p = source;
49 for (j = 0; j < k; j++)
50 *dest++ = (gfc_char4_t) *p++;
53 /* This include contains the heart and soul of formatted floating point. */
54 #include "write_float.def"
56 /* Write out default char4. */
58 static void
59 write_default_char4 (st_parameter_dt *dtp, const gfc_char4_t *source,
60 int src_len, int w_len)
62 char *p;
63 int j, k = 0;
64 gfc_char4_t c;
65 uchar d;
67 /* Take care of preceding blanks. */
68 if (w_len > src_len)
70 k = w_len - src_len;
71 p = write_block (dtp, k);
72 if (p == NULL)
73 return;
74 if (is_char4_unit (dtp))
76 gfc_char4_t *p4 = (gfc_char4_t *) p;
77 memset4 (p4, ' ', k);
79 else
80 memset (p, ' ', k);
83 /* Get ready to handle delimiters if needed. */
84 switch (dtp->u.p.current_unit->delim_status)
86 case DELIM_APOSTROPHE:
87 d = '\'';
88 break;
89 case DELIM_QUOTE:
90 d = '"';
91 break;
92 default:
93 d = ' ';
94 break;
97 /* Now process the remaining characters, one at a time. */
98 for (j = 0; j < src_len; j++)
100 c = source[j];
101 if (is_char4_unit (dtp))
103 gfc_char4_t *q;
104 /* Handle delimiters if any. */
105 if (c == d && d != ' ')
107 p = write_block (dtp, 2);
108 if (p == NULL)
109 return;
110 q = (gfc_char4_t *) p;
111 *q++ = c;
113 else
115 p = write_block (dtp, 1);
116 if (p == NULL)
117 return;
118 q = (gfc_char4_t *) p;
120 *q = c;
122 else
124 /* Handle delimiters if any. */
125 if (c == d && d != ' ')
127 p = write_block (dtp, 2);
128 if (p == NULL)
129 return;
130 *p++ = (uchar) c;
132 else
134 p = write_block (dtp, 1);
135 if (p == NULL)
136 return;
138 *p = c > 255 ? '?' : (uchar) c;
144 /* Write out UTF-8 converted from char4. */
146 static void
147 write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
148 int src_len, int w_len)
150 char *p;
151 int j, k = 0;
152 gfc_char4_t c;
153 static const uchar masks[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
154 static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
155 int nbytes;
156 uchar buf[6], d, *q;
158 /* Take care of preceding blanks. */
159 if (w_len > src_len)
161 k = w_len - src_len;
162 p = write_block (dtp, k);
163 if (p == NULL)
164 return;
165 memset (p, ' ', k);
168 /* Get ready to handle delimiters if needed. */
169 switch (dtp->u.p.current_unit->delim_status)
171 case DELIM_APOSTROPHE:
172 d = '\'';
173 break;
174 case DELIM_QUOTE:
175 d = '"';
176 break;
177 default:
178 d = ' ';
179 break;
182 /* Now process the remaining characters, one at a time. */
183 for (j = k; j < src_len; j++)
185 c = source[j];
186 if (c < 0x80)
188 /* Handle the delimiters if any. */
189 if (c == d && d != ' ')
191 p = write_block (dtp, 2);
192 if (p == NULL)
193 return;
194 *p++ = (uchar) c;
196 else
198 p = write_block (dtp, 1);
199 if (p == NULL)
200 return;
202 *p = (uchar) c;
204 else
206 /* Convert to UTF-8 sequence. */
207 nbytes = 1;
208 q = &buf[6];
212 *--q = ((c & 0x3F) | 0x80);
213 c >>= 6;
214 nbytes++;
216 while (c >= 0x3F || (c & limits[nbytes-1]));
218 *--q = (c | masks[nbytes-1]);
220 p = write_block (dtp, nbytes);
221 if (p == NULL)
222 return;
224 while (q < &buf[6])
225 *p++ = *q++;
231 void
232 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
234 int wlen;
235 char *p;
237 wlen = f->u.string.length < 0
238 || (f->format == FMT_G && f->u.string.length == 0)
239 ? len : f->u.string.length;
241 #ifdef HAVE_CRLF
242 /* If this is formatted STREAM IO convert any embedded line feed characters
243 to CR_LF on systems that use that sequence for newlines. See F2003
244 Standard sections 10.6.3 and 9.9 for further information. */
245 if (is_stream_io (dtp))
247 const char crlf[] = "\r\n";
248 int i, q, bytes;
249 q = bytes = 0;
251 /* Write out any padding if needed. */
252 if (len < wlen)
254 p = write_block (dtp, wlen - len);
255 if (p == NULL)
256 return;
257 memset (p, ' ', wlen - len);
260 /* Scan the source string looking for '\n' and convert it if found. */
261 for (i = 0; i < wlen; i++)
263 if (source[i] == '\n')
265 /* Write out the previously scanned characters in the string. */
266 if (bytes > 0)
268 p = write_block (dtp, bytes);
269 if (p == NULL)
270 return;
271 memcpy (p, &source[q], bytes);
272 q += bytes;
273 bytes = 0;
276 /* Write out the CR_LF sequence. */
277 q++;
278 p = write_block (dtp, 2);
279 if (p == NULL)
280 return;
281 memcpy (p, crlf, 2);
283 else
284 bytes++;
287 /* Write out any remaining bytes if no LF was found. */
288 if (bytes > 0)
290 p = write_block (dtp, bytes);
291 if (p == NULL)
292 return;
293 memcpy (p, &source[q], bytes);
296 else
298 #endif
299 p = write_block (dtp, wlen);
300 if (p == NULL)
301 return;
303 if (unlikely (is_char4_unit (dtp)))
305 gfc_char4_t *p4 = (gfc_char4_t *) p;
306 if (wlen < len)
307 memcpy4 (p4, source, wlen);
308 else
310 memset4 (p4, ' ', wlen - len);
311 memcpy4 (p4 + wlen - len, source, len);
313 return;
316 if (wlen < len)
317 memcpy (p, source, wlen);
318 else
320 memset (p, ' ', wlen - len);
321 memcpy (p + wlen - len, source, len);
323 #ifdef HAVE_CRLF
325 #endif
329 /* The primary difference between write_a_char4 and write_a is that we have to
330 deal with writing from the first byte of the 4-byte character and pay
331 attention to the most significant bytes. For ENCODING="default" write the
332 lowest significant byte. If the 3 most significant bytes contain
333 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
334 to the UTF-8 encoded string before writing out. */
336 void
337 write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
339 int wlen;
340 gfc_char4_t *q;
342 wlen = f->u.string.length < 0
343 || (f->format == FMT_G && f->u.string.length == 0)
344 ? len : f->u.string.length;
346 q = (gfc_char4_t *) source;
347 #ifdef HAVE_CRLF
348 /* If this is formatted STREAM IO convert any embedded line feed characters
349 to CR_LF on systems that use that sequence for newlines. See F2003
350 Standard sections 10.6.3 and 9.9 for further information. */
351 if (is_stream_io (dtp))
353 const gfc_char4_t crlf[] = {0x000d,0x000a};
354 int i, bytes;
355 gfc_char4_t *qq;
356 bytes = 0;
358 /* Write out any padding if needed. */
359 if (len < wlen)
361 char *p;
362 p = write_block (dtp, wlen - len);
363 if (p == NULL)
364 return;
365 memset (p, ' ', wlen - len);
368 /* Scan the source string looking for '\n' and convert it if found. */
369 qq = (gfc_char4_t *) source;
370 for (i = 0; i < wlen; i++)
372 if (qq[i] == '\n')
374 /* Write out the previously scanned characters in the string. */
375 if (bytes > 0)
377 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
378 write_utf8_char4 (dtp, q, bytes, 0);
379 else
380 write_default_char4 (dtp, q, bytes, 0);
381 bytes = 0;
384 /* Write out the CR_LF sequence. */
385 write_default_char4 (dtp, crlf, 2, 0);
387 else
388 bytes++;
391 /* Write out any remaining bytes if no LF was found. */
392 if (bytes > 0)
394 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
395 write_utf8_char4 (dtp, q, bytes, 0);
396 else
397 write_default_char4 (dtp, q, bytes, 0);
400 else
402 #endif
403 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
404 write_utf8_char4 (dtp, q, len, wlen);
405 else
406 write_default_char4 (dtp, q, len, wlen);
407 #ifdef HAVE_CRLF
409 #endif
413 static GFC_INTEGER_LARGEST
414 extract_int (const void *p, int len)
416 GFC_INTEGER_LARGEST i = 0;
418 if (p == NULL)
419 return i;
421 switch (len)
423 case 1:
425 GFC_INTEGER_1 tmp;
426 memcpy ((void *) &tmp, p, len);
427 i = tmp;
429 break;
430 case 2:
432 GFC_INTEGER_2 tmp;
433 memcpy ((void *) &tmp, p, len);
434 i = tmp;
436 break;
437 case 4:
439 GFC_INTEGER_4 tmp;
440 memcpy ((void *) &tmp, p, len);
441 i = tmp;
443 break;
444 case 8:
446 GFC_INTEGER_8 tmp;
447 memcpy ((void *) &tmp, p, len);
448 i = tmp;
450 break;
451 #ifdef HAVE_GFC_INTEGER_16
452 case 16:
454 GFC_INTEGER_16 tmp;
455 memcpy ((void *) &tmp, p, len);
456 i = tmp;
458 break;
459 #endif
460 default:
461 internal_error (NULL, "bad integer kind");
464 return i;
467 static GFC_UINTEGER_LARGEST
468 extract_uint (const void *p, int len)
470 GFC_UINTEGER_LARGEST i = 0;
472 if (p == NULL)
473 return i;
475 switch (len)
477 case 1:
479 GFC_INTEGER_1 tmp;
480 memcpy ((void *) &tmp, p, len);
481 i = (GFC_UINTEGER_1) tmp;
483 break;
484 case 2:
486 GFC_INTEGER_2 tmp;
487 memcpy ((void *) &tmp, p, len);
488 i = (GFC_UINTEGER_2) tmp;
490 break;
491 case 4:
493 GFC_INTEGER_4 tmp;
494 memcpy ((void *) &tmp, p, len);
495 i = (GFC_UINTEGER_4) tmp;
497 break;
498 case 8:
500 GFC_INTEGER_8 tmp;
501 memcpy ((void *) &tmp, p, len);
502 i = (GFC_UINTEGER_8) tmp;
504 break;
505 #ifdef HAVE_GFC_INTEGER_16
506 case 10:
507 case 16:
509 GFC_INTEGER_16 tmp = 0;
510 memcpy ((void *) &tmp, p, len);
511 i = (GFC_UINTEGER_16) tmp;
513 break;
514 #endif
515 default:
516 internal_error (NULL, "bad integer kind");
519 return i;
523 void
524 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
526 char *p;
527 int wlen;
528 GFC_INTEGER_LARGEST n;
530 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
532 p = write_block (dtp, wlen);
533 if (p == NULL)
534 return;
536 n = extract_int (source, len);
538 if (unlikely (is_char4_unit (dtp)))
540 gfc_char4_t *p4 = (gfc_char4_t *) p;
541 memset4 (p4, ' ', wlen -1);
542 p4[wlen - 1] = (n) ? 'T' : 'F';
543 return;
546 memset (p, ' ', wlen -1);
547 p[wlen - 1] = (n) ? 'T' : 'F';
551 static void
552 write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
554 int w, m, digits, nzero, nblank;
555 char *p;
557 w = f->u.integer.w;
558 m = f->u.integer.m;
560 /* Special case: */
562 if (m == 0 && n == 0)
564 if (w == 0)
565 w = 1;
567 p = write_block (dtp, w);
568 if (p == NULL)
569 return;
570 if (unlikely (is_char4_unit (dtp)))
572 gfc_char4_t *p4 = (gfc_char4_t *) p;
573 memset4 (p4, ' ', w);
575 else
576 memset (p, ' ', w);
577 goto done;
580 digits = strlen (q);
582 /* Select a width if none was specified. The idea here is to always
583 print something. */
585 if (w == 0)
586 w = ((digits < m) ? m : digits);
588 p = write_block (dtp, w);
589 if (p == NULL)
590 return;
592 nzero = 0;
593 if (digits < m)
594 nzero = m - digits;
596 /* See if things will work. */
598 nblank = w - (nzero + digits);
600 if (unlikely (is_char4_unit (dtp)))
602 gfc_char4_t *p4 = (gfc_char4_t *) p;
603 if (nblank < 0)
605 memset4 (p4, '*', w);
606 return;
609 if (!dtp->u.p.no_leading_blank)
611 memset4 (p4, ' ', nblank);
612 q += nblank;
613 memset4 (p4, '0', nzero);
614 q += nzero;
615 memcpy4 (p4, q, digits);
617 else
619 memset4 (p4, '0', nzero);
620 q += nzero;
621 memcpy4 (p4, q, digits);
622 q += digits;
623 memset4 (p4, ' ', nblank);
624 dtp->u.p.no_leading_blank = 0;
626 return;
629 if (nblank < 0)
631 star_fill (p, w);
632 goto done;
635 if (!dtp->u.p.no_leading_blank)
637 memset (p, ' ', nblank);
638 p += nblank;
639 memset (p, '0', nzero);
640 p += nzero;
641 memcpy (p, q, digits);
643 else
645 memset (p, '0', nzero);
646 p += nzero;
647 memcpy (p, q, digits);
648 p += digits;
649 memset (p, ' ', nblank);
650 dtp->u.p.no_leading_blank = 0;
653 done:
654 return;
657 static void
658 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
659 int len,
660 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
662 GFC_INTEGER_LARGEST n = 0;
663 int w, m, digits, nsign, nzero, nblank;
664 char *p;
665 const char *q;
666 sign_t sign;
667 char itoa_buf[GFC_BTOA_BUF_SIZE];
669 w = f->u.integer.w;
670 m = f->format == FMT_G ? -1 : f->u.integer.m;
672 n = extract_int (source, len);
674 /* Special case: */
675 if (m == 0 && n == 0)
677 if (w == 0)
678 w = 1;
680 p = write_block (dtp, w);
681 if (p == NULL)
682 return;
683 if (unlikely (is_char4_unit (dtp)))
685 gfc_char4_t *p4 = (gfc_char4_t *) p;
686 memset4 (p4, ' ', w);
688 else
689 memset (p, ' ', w);
690 goto done;
693 sign = calculate_sign (dtp, n < 0);
694 if (n < 0)
695 n = -n;
696 nsign = sign == S_NONE ? 0 : 1;
698 /* conv calls itoa which sets the negative sign needed
699 by write_integer. The sign '+' or '-' is set below based on sign
700 calculated above, so we just point past the sign in the string
701 before proceeding to avoid double signs in corner cases.
702 (see PR38504) */
703 q = conv (n, itoa_buf, sizeof (itoa_buf));
704 if (*q == '-')
705 q++;
707 digits = strlen (q);
709 /* Select a width if none was specified. The idea here is to always
710 print something. */
712 if (w == 0)
713 w = ((digits < m) ? m : digits) + nsign;
715 p = write_block (dtp, w);
716 if (p == NULL)
717 return;
719 nzero = 0;
720 if (digits < m)
721 nzero = m - digits;
723 /* See if things will work. */
725 nblank = w - (nsign + nzero + digits);
727 if (unlikely (is_char4_unit (dtp)))
729 gfc_char4_t * p4 = (gfc_char4_t *) p;
730 if (nblank < 0)
732 memset4 (p4, '*', w);
733 goto done;
736 memset4 (p4, ' ', nblank);
737 p4 += nblank;
739 switch (sign)
741 case S_PLUS:
742 *p4++ = '+';
743 break;
744 case S_MINUS:
745 *p4++ = '-';
746 break;
747 case S_NONE:
748 break;
751 memset4 (p4, '0', nzero);
752 p4 += nzero;
754 memcpy4 (p4, q, digits);
755 return;
758 if (nblank < 0)
760 star_fill (p, w);
761 goto done;
764 memset (p, ' ', nblank);
765 p += nblank;
767 switch (sign)
769 case S_PLUS:
770 *p++ = '+';
771 break;
772 case S_MINUS:
773 *p++ = '-';
774 break;
775 case S_NONE:
776 break;
779 memset (p, '0', nzero);
780 p += nzero;
782 memcpy (p, q, digits);
784 done:
785 return;
789 /* Convert unsigned octal to ascii. */
791 static const char *
792 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
794 char *p;
796 assert (len >= GFC_OTOA_BUF_SIZE);
798 if (n == 0)
799 return "0";
801 p = buffer + GFC_OTOA_BUF_SIZE - 1;
802 *p = '\0';
804 while (n != 0)
806 *--p = '0' + (n & 7);
807 n >>= 3;
810 return p;
814 /* Convert unsigned binary to ascii. */
816 static const char *
817 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
819 char *p;
821 assert (len >= GFC_BTOA_BUF_SIZE);
823 if (n == 0)
824 return "0";
826 p = buffer + GFC_BTOA_BUF_SIZE - 1;
827 *p = '\0';
829 while (n != 0)
831 *--p = '0' + (n & 1);
832 n >>= 1;
835 return p;
838 /* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
839 to convert large reals with kind sizes that exceed the largest integer type
840 available on certain platforms. In these cases, byte by byte conversion is
841 performed. Endianess is taken into account. */
843 /* Conversion to binary. */
845 static const char *
846 btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
848 char *q;
849 int i, j;
851 q = buffer;
852 if (big_endian)
854 const char *p = s;
855 for (i = 0; i < len; i++)
857 char c = *p;
859 /* Test for zero. Needed by write_boz later. */
860 if (*p != 0)
861 *n = 1;
863 for (j = 0; j < 8; j++)
865 *q++ = (c & 128) ? '1' : '0';
866 c <<= 1;
868 p++;
871 else
873 const char *p = s + len - 1;
874 for (i = 0; i < len; i++)
876 char c = *p;
878 /* Test for zero. Needed by write_boz later. */
879 if (*p != 0)
880 *n = 1;
882 for (j = 0; j < 8; j++)
884 *q++ = (c & 128) ? '1' : '0';
885 c <<= 1;
887 p--;
891 *q = '\0';
893 if (*n == 0)
894 return "0";
896 /* Move past any leading zeros. */
897 while (*buffer == '0')
898 buffer++;
900 return buffer;
904 /* Conversion to octal. */
906 static const char *
907 otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
909 char *q;
910 int i, j, k;
911 uint8_t octet;
913 q = buffer + GFC_OTOA_BUF_SIZE - 1;
914 *q = '\0';
915 i = k = octet = 0;
917 if (big_endian)
919 const char *p = s + len - 1;
920 char c = *p;
921 while (i < len)
923 /* Test for zero. Needed by write_boz later. */
924 if (*p != 0)
925 *n = 1;
927 for (j = 0; j < 3 && i < len; j++)
929 octet |= (c & 1) << j;
930 c >>= 1;
931 if (++k > 7)
933 i++;
934 k = 0;
935 c = *--p;
938 *--q = '0' + octet;
939 octet = 0;
942 else
944 const char *p = s;
945 char c = *p;
946 while (i < len)
948 /* Test for zero. Needed by write_boz later. */
949 if (*p != 0)
950 *n = 1;
952 for (j = 0; j < 3 && i < len; j++)
954 octet |= (c & 1) << j;
955 c >>= 1;
956 if (++k > 7)
958 i++;
959 k = 0;
960 c = *++p;
963 *--q = '0' + octet;
964 octet = 0;
968 if (*n == 0)
969 return "0";
971 /* Move past any leading zeros. */
972 while (*q == '0')
973 q++;
975 return q;
978 /* Conversion to hexidecimal. */
980 static const char *
981 ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
983 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
984 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
986 char *q;
987 uint8_t h, l;
988 int i;
990 q = buffer;
992 if (big_endian)
994 const char *p = s;
995 for (i = 0; i < len; i++)
997 /* Test for zero. Needed by write_boz later. */
998 if (*p != 0)
999 *n = 1;
1001 h = (*p >> 4) & 0x0F;
1002 l = *p++ & 0x0F;
1003 *q++ = a[h];
1004 *q++ = a[l];
1007 else
1009 const char *p = s + len - 1;
1010 for (i = 0; i < len; i++)
1012 /* Test for zero. Needed by write_boz later. */
1013 if (*p != 0)
1014 *n = 1;
1016 h = (*p >> 4) & 0x0F;
1017 l = *p-- & 0x0F;
1018 *q++ = a[h];
1019 *q++ = a[l];
1023 *q = '\0';
1025 if (*n == 0)
1026 return "0";
1028 /* Move past any leading zeros. */
1029 while (*buffer == '0')
1030 buffer++;
1032 return buffer;
1036 void
1037 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1039 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
1043 void
1044 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1046 const char *p;
1047 char itoa_buf[GFC_BTOA_BUF_SIZE];
1048 GFC_UINTEGER_LARGEST n = 0;
1050 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1052 p = btoa_big (source, itoa_buf, len, &n);
1053 write_boz (dtp, f, p, n);
1055 else
1057 n = extract_uint (source, len);
1058 p = btoa (n, itoa_buf, sizeof (itoa_buf));
1059 write_boz (dtp, f, p, n);
1064 void
1065 write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1067 const char *p;
1068 char itoa_buf[GFC_OTOA_BUF_SIZE];
1069 GFC_UINTEGER_LARGEST n = 0;
1071 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1073 p = otoa_big (source, itoa_buf, len, &n);
1074 write_boz (dtp, f, p, n);
1076 else
1078 n = extract_uint (source, len);
1079 p = otoa (n, itoa_buf, sizeof (itoa_buf));
1080 write_boz (dtp, f, p, n);
1084 void
1085 write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1087 const char *p;
1088 char itoa_buf[GFC_XTOA_BUF_SIZE];
1089 GFC_UINTEGER_LARGEST n = 0;
1091 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1093 p = ztoa_big (source, itoa_buf, len, &n);
1094 write_boz (dtp, f, p, n);
1096 else
1098 n = extract_uint (source, len);
1099 p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
1100 write_boz (dtp, f, p, n);
1104 /* Take care of the X/TR descriptor. */
1106 void
1107 write_x (st_parameter_dt *dtp, int len, int nspaces)
1109 char *p;
1111 p = write_block (dtp, len);
1112 if (p == NULL)
1113 return;
1114 if (nspaces > 0 && len - nspaces >= 0)
1116 if (unlikely (is_char4_unit (dtp)))
1118 gfc_char4_t *p4 = (gfc_char4_t *) p;
1119 memset4 (&p4[len - nspaces], ' ', nspaces);
1121 else
1122 memset (&p[len - nspaces], ' ', nspaces);
1127 /* List-directed writing. */
1130 /* Write a single character to the output. Returns nonzero if
1131 something goes wrong. */
1133 static int
1134 write_char (st_parameter_dt *dtp, int c)
1136 char *p;
1138 p = write_block (dtp, 1);
1139 if (p == NULL)
1140 return 1;
1141 if (unlikely (is_char4_unit (dtp)))
1143 gfc_char4_t *p4 = (gfc_char4_t *) p;
1144 *p4 = c;
1145 return 0;
1148 *p = (uchar) c;
1150 return 0;
1154 /* Write a list-directed logical value. */
1156 static void
1157 write_logical (st_parameter_dt *dtp, const char *source, int length)
1159 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
1163 /* Write a list-directed integer value. */
1165 static void
1166 write_integer (st_parameter_dt *dtp, const char *source, int length)
1168 char *p;
1169 const char *q;
1170 int digits;
1171 int width;
1172 char itoa_buf[GFC_ITOA_BUF_SIZE];
1174 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1176 switch (length)
1178 case 1:
1179 width = 4;
1180 break;
1182 case 2:
1183 width = 6;
1184 break;
1186 case 4:
1187 width = 11;
1188 break;
1190 case 8:
1191 width = 20;
1192 break;
1194 default:
1195 width = 0;
1196 break;
1199 digits = strlen (q);
1201 if (width < digits)
1202 width = digits;
1203 p = write_block (dtp, width);
1204 if (p == NULL)
1205 return;
1207 if (unlikely (is_char4_unit (dtp)))
1209 gfc_char4_t *p4 = (gfc_char4_t *) p;
1210 if (dtp->u.p.no_leading_blank)
1212 memcpy4 (p4, q, digits);
1213 memset4 (p4 + digits, ' ', width - digits);
1215 else
1217 memset4 (p4, ' ', width - digits);
1218 memcpy4 (p4 + width - digits, q, digits);
1220 return;
1223 if (dtp->u.p.no_leading_blank)
1225 memcpy (p, q, digits);
1226 memset (p + digits, ' ', width - digits);
1228 else
1230 memset (p, ' ', width - digits);
1231 memcpy (p + width - digits, q, digits);
1236 /* Write a list-directed string. We have to worry about delimiting
1237 the strings if the file has been opened in that mode. */
1239 #define DELIM 1
1240 #define NODELIM 0
1242 static void
1243 write_character (st_parameter_dt *dtp, const char *source, int kind, int length, int mode)
1245 int i, extra;
1246 char *p, d;
1248 if (mode == DELIM)
1250 switch (dtp->u.p.current_unit->delim_status)
1252 case DELIM_APOSTROPHE:
1253 d = '\'';
1254 break;
1255 case DELIM_QUOTE:
1256 d = '"';
1257 break;
1258 default:
1259 d = ' ';
1260 break;
1263 else
1264 d = ' ';
1266 if (kind == 1)
1268 if (d == ' ')
1269 extra = 0;
1270 else
1272 extra = 2;
1274 for (i = 0; i < length; i++)
1275 if (source[i] == d)
1276 extra++;
1279 p = write_block (dtp, length + extra);
1280 if (p == NULL)
1281 return;
1283 if (unlikely (is_char4_unit (dtp)))
1285 gfc_char4_t d4 = (gfc_char4_t) d;
1286 gfc_char4_t *p4 = (gfc_char4_t *) p;
1288 if (d4 == ' ')
1289 memcpy4 (p4, source, length);
1290 else
1292 *p4++ = d4;
1294 for (i = 0; i < length; i++)
1296 *p4++ = (gfc_char4_t) source[i];
1297 if (source[i] == d)
1298 *p4++ = d4;
1301 *p4 = d4;
1303 return;
1306 if (d == ' ')
1307 memcpy (p, source, length);
1308 else
1310 *p++ = d;
1312 for (i = 0; i < length; i++)
1314 *p++ = source[i];
1315 if (source[i] == d)
1316 *p++ = d;
1319 *p = d;
1322 else
1324 if (d == ' ')
1326 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1327 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1328 else
1329 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1331 else
1333 p = write_block (dtp, 1);
1334 *p = d;
1336 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1337 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1338 else
1339 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1341 p = write_block (dtp, 1);
1342 *p = d;
1347 /* Floating point helper functions. */
1349 #define BUF_STACK_SZ 256
1351 static int
1352 get_precision (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1354 if (f->format != FMT_EN)
1355 return determine_precision (dtp, f, kind);
1356 else
1357 return determine_en_precision (dtp, f, source, kind);
1360 static char *
1361 select_buffer (int precision, char *buf, size_t *size)
1363 char *result;
1364 *size = BUF_STACK_SZ / 2 + precision;
1365 if (*size > BUF_STACK_SZ)
1366 result = xmalloc (*size);
1367 else
1368 result = buf;
1369 return result;
1372 static char *
1373 select_string (const fnode *f, char *buf, size_t *size)
1375 char *result;
1376 *size = f->u.real.w + 1;
1377 if (*size > BUF_STACK_SZ)
1378 result = xmalloc (*size);
1379 else
1380 result = buf;
1381 return result;
1384 static void
1385 write_float_string (st_parameter_dt *dtp, char *fstr, size_t len)
1387 char *p = write_block (dtp, len);
1388 if (p == NULL)
1389 return;
1391 if (unlikely (is_char4_unit (dtp)))
1393 gfc_char4_t *p4 = (gfc_char4_t *) p;
1394 memcpy4 (p4, fstr, len);
1395 return;
1397 memcpy (p, fstr, len);
1400 static void
1401 write_float_0 (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1403 char buf_stack[BUF_STACK_SZ];
1404 char str_buf[BUF_STACK_SZ];
1405 char *buffer, *result;
1406 size_t buf_size, res_len;
1408 /* Precision for snprintf call. */
1409 int precision = get_precision (dtp, f, source, kind);
1411 /* String buffer to hold final result. */
1412 result = select_string (f, str_buf, &res_len);
1414 buffer = select_buffer (precision, buf_stack, &buf_size);
1416 get_float_string (dtp, f, source , kind, 0, buffer,
1417 precision, buf_size, result, &res_len);
1418 write_float_string (dtp, result, res_len);
1420 if (buf_size > BUF_STACK_SZ)
1421 free (buffer);
1422 if (res_len > BUF_STACK_SZ)
1423 free (result);
1426 void
1427 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1429 write_float_0 (dtp, f, p, len);
1433 void
1434 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1436 write_float_0 (dtp, f, p, len);
1440 void
1441 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1443 write_float_0 (dtp, f, p, len);
1447 void
1448 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1450 write_float_0 (dtp, f, p, len);
1454 void
1455 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1457 write_float_0 (dtp, f, p, len);
1461 /* Set an fnode to default format. */
1463 static void
1464 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
1466 f->format = FMT_G;
1467 switch (length)
1469 case 4:
1470 f->u.real.w = 16;
1471 f->u.real.d = 9;
1472 f->u.real.e = 2;
1473 break;
1474 case 8:
1475 f->u.real.w = 25;
1476 f->u.real.d = 17;
1477 f->u.real.e = 3;
1478 break;
1479 case 10:
1480 f->u.real.w = 30;
1481 f->u.real.d = 21;
1482 f->u.real.e = 4;
1483 break;
1484 case 16:
1485 /* Adjust decimal precision depending on binary precision, 106 or 113. */
1486 #if GFC_REAL_16_DIGITS == 113
1487 f->u.real.w = 45;
1488 f->u.real.d = 36;
1489 f->u.real.e = 4;
1490 #else
1491 f->u.real.w = 41;
1492 f->u.real.d = 32;
1493 f->u.real.e = 4;
1494 #endif
1495 break;
1496 default:
1497 internal_error (&dtp->common, "bad real kind");
1498 break;
1502 /* Output a real number with default format.
1503 To guarantee that a binary -> decimal -> binary roundtrip conversion
1504 recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
1505 significant digits for REAL kinds 4, 8, 10, and 16, respectively.
1506 Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
1507 for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
1508 Fortran standard requires outputting an extra digit when the scale
1509 factor is 1 and when the magnitude of the value is such that E
1510 editing is used. However, gfortran compensates for this, and thus
1511 for list formatted the same number of significant digits is
1512 generated both when using F and E editing. */
1514 void
1515 write_real (st_parameter_dt *dtp, const char *source, int kind)
1517 fnode f ;
1518 char buf_stack[BUF_STACK_SZ];
1519 char str_buf[BUF_STACK_SZ];
1520 char *buffer, *result;
1521 size_t buf_size, res_len;
1522 int orig_scale = dtp->u.p.scale_factor;
1523 dtp->u.p.scale_factor = 1;
1524 set_fnode_default (dtp, &f, kind);
1526 /* Precision for snprintf call. */
1527 int precision = get_precision (dtp, &f, source, kind);
1529 /* String buffer to hold final result. */
1530 result = select_string (&f, str_buf, &res_len);
1532 /* scratch buffer to hold final result. */
1533 buffer = select_buffer (precision, buf_stack, &buf_size);
1535 get_float_string (dtp, &f, source , kind, 1, buffer,
1536 precision, buf_size, result, &res_len);
1537 write_float_string (dtp, result, res_len);
1539 dtp->u.p.scale_factor = orig_scale;
1540 if (buf_size > BUF_STACK_SZ)
1541 free (buffer);
1542 if (res_len > BUF_STACK_SZ)
1543 free (result);
1546 /* Similar to list formatted REAL output, for kPG0 where k > 0 we
1547 compensate for the extra digit. */
1549 void
1550 write_real_g0 (st_parameter_dt *dtp, const char *source, int kind, int d)
1552 fnode f;
1553 char buf_stack[BUF_STACK_SZ];
1554 char str_buf[BUF_STACK_SZ];
1555 char *buffer, *result;
1556 size_t buf_size, res_len;
1557 int comp_d;
1558 set_fnode_default (dtp, &f, kind);
1560 if (d > 0)
1561 f.u.real.d = d;
1563 /* Compensate for extra digits when using scale factor, d is not
1564 specified, and the magnitude is such that E editing is used. */
1565 if (dtp->u.p.scale_factor > 0 && d == 0)
1566 comp_d = 1;
1567 else
1568 comp_d = 0;
1569 dtp->u.p.g0_no_blanks = 1;
1571 /* Precision for snprintf call. */
1572 int precision = get_precision (dtp, &f, source, kind);
1574 /* String buffer to hold final result. */
1575 result = select_string (&f, str_buf, &res_len);
1577 buffer = select_buffer (precision, buf_stack, &buf_size);
1579 get_float_string (dtp, &f, source , kind, comp_d, buffer,
1580 precision, buf_size, result, &res_len);
1581 write_float_string (dtp, result, res_len);
1583 dtp->u.p.g0_no_blanks = 0;
1584 if (buf_size > BUF_STACK_SZ)
1585 free (buffer);
1586 if (res_len > BUF_STACK_SZ)
1587 free (result);
1591 static void
1592 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1594 char semi_comma =
1595 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1597 /* Set for no blanks so we get a string result with no leading
1598 blanks. We will pad left later. */
1599 dtp->u.p.g0_no_blanks = 1;
1601 fnode f ;
1602 char buf_stack[BUF_STACK_SZ];
1603 char str1_buf[BUF_STACK_SZ];
1604 char str2_buf[BUF_STACK_SZ];
1605 char *buffer, *result1, *result2;
1606 size_t buf_size, res_len1, res_len2;
1607 int width, lblanks, orig_scale = dtp->u.p.scale_factor;
1609 dtp->u.p.scale_factor = 1;
1610 set_fnode_default (dtp, &f, kind);
1612 /* Set width for two values, parenthesis, and comma. */
1613 width = 2 * f.u.real.w + 3;
1615 /* Set for no blanks so we get a string result with no leading
1616 blanks. We will pad left later. */
1617 dtp->u.p.g0_no_blanks = 1;
1619 /* Precision for snprintf call. */
1620 int precision = get_precision (dtp, &f, source, kind);
1622 /* String buffers to hold final result. */
1623 result1 = select_string (&f, str1_buf, &res_len1);
1624 result2 = select_string (&f, str2_buf, &res_len2);
1626 buffer = select_buffer (precision, buf_stack, &buf_size);
1628 get_float_string (dtp, &f, source , kind, 0, buffer,
1629 precision, buf_size, result1, &res_len1);
1630 get_float_string (dtp, &f, source + size / 2 , kind, 0, buffer,
1631 precision, buf_size, result2, &res_len2);
1632 lblanks = width - res_len1 - res_len2 - 3;
1634 write_x (dtp, lblanks, lblanks);
1635 write_char (dtp, '(');
1636 write_float_string (dtp, result1, res_len1);
1637 write_char (dtp, semi_comma);
1638 write_float_string (dtp, result2, res_len2);
1639 write_char (dtp, ')');
1641 dtp->u.p.scale_factor = orig_scale;
1642 dtp->u.p.g0_no_blanks = 0;
1643 if (buf_size > BUF_STACK_SZ)
1644 free (buffer);
1645 if (res_len1 > BUF_STACK_SZ)
1646 free (result1);
1647 if (res_len2 > BUF_STACK_SZ)
1648 free (result2);
1652 /* Write the separator between items. */
1654 static void
1655 write_separator (st_parameter_dt *dtp)
1657 char *p;
1659 p = write_block (dtp, options.separator_len);
1660 if (p == NULL)
1661 return;
1662 if (unlikely (is_char4_unit (dtp)))
1664 gfc_char4_t *p4 = (gfc_char4_t *) p;
1665 memcpy4 (p4, options.separator, options.separator_len);
1667 else
1668 memcpy (p, options.separator, options.separator_len);
1672 /* Write an item with list formatting.
1673 TODO: handle skipping to the next record correctly, particularly
1674 with strings. */
1676 static void
1677 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1678 size_t size)
1680 if (dtp->u.p.current_unit == NULL)
1681 return;
1683 if (dtp->u.p.first_item)
1685 dtp->u.p.first_item = 0;
1686 write_char (dtp, ' ');
1688 else
1690 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1691 (dtp->u.p.current_unit->delim_status != DELIM_NONE
1692 && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
1693 write_separator (dtp);
1696 switch (type)
1698 case BT_INTEGER:
1699 write_integer (dtp, p, kind);
1700 break;
1701 case BT_LOGICAL:
1702 write_logical (dtp, p, kind);
1703 break;
1704 case BT_CHARACTER:
1705 write_character (dtp, p, kind, size, DELIM);
1706 break;
1707 case BT_REAL:
1708 write_real (dtp, p, kind);
1709 break;
1710 case BT_COMPLEX:
1711 write_complex (dtp, p, kind, size);
1712 break;
1713 case BT_CLASS:
1715 int unit = dtp->u.p.current_unit->unit_number;
1716 char iotype[] = "LISTDIRECTED";
1717 gfc_charlen_type iotype_len = 12;
1718 char tmp_iomsg[IOMSG_LEN] = "";
1719 char *child_iomsg;
1720 gfc_charlen_type child_iomsg_len;
1721 int noiostat;
1722 int *child_iostat = NULL;
1723 gfc_array_i4 vlist;
1725 GFC_DESCRIPTOR_DATA(&vlist) = NULL;
1726 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
1728 /* Set iostat, intent(out). */
1729 noiostat = 0;
1730 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1731 dtp->common.iostat : &noiostat;
1733 /* Set iomsge, intent(inout). */
1734 if (dtp->common.flags & IOPARM_HAS_IOMSG)
1736 child_iomsg = dtp->common.iomsg;
1737 child_iomsg_len = dtp->common.iomsg_len;
1739 else
1741 child_iomsg = tmp_iomsg;
1742 child_iomsg_len = IOMSG_LEN;
1745 /* Call the user defined formatted WRITE procedure. */
1746 dtp->u.p.current_unit->child_dtio++;
1747 dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
1748 child_iostat, child_iomsg,
1749 iotype_len, child_iomsg_len);
1750 dtp->u.p.current_unit->child_dtio--;
1752 break;
1753 default:
1754 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1757 fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
1758 dtp->u.p.char_flag = (type == BT_CHARACTER);
1762 void
1763 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1764 size_t size, size_t nelems)
1766 size_t elem;
1767 char *tmp;
1768 size_t stride = type == BT_CHARACTER ?
1769 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1771 tmp = (char *) p;
1773 /* Big loop over all the elements. */
1774 for (elem = 0; elem < nelems; elem++)
1776 dtp->u.p.item_count++;
1777 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
1781 /* NAMELIST OUTPUT
1783 nml_write_obj writes a namelist object to the output stream. It is called
1784 recursively for derived type components:
1785 obj = is the namelist_info for the current object.
1786 offset = the offset relative to the address held by the object for
1787 derived type arrays.
1788 base = is the namelist_info of the derived type, when obj is a
1789 component.
1790 base_name = the full name for a derived type, including qualifiers
1791 if any.
1792 The returned value is a pointer to the object beyond the last one
1793 accessed, including nested derived types. Notice that the namelist is
1794 a linear linked list of objects, including derived types and their
1795 components. A tree, of sorts, is implied by the compound names of
1796 the derived type components and this is how this function recurses through
1797 the list. */
1799 /* A generous estimate of the number of characters needed to print
1800 repeat counts and indices, including commas, asterices and brackets. */
1802 #define NML_DIGITS 20
1804 static void
1805 namelist_write_newline (st_parameter_dt *dtp)
1807 if (!is_internal_unit (dtp))
1809 #ifdef HAVE_CRLF
1810 write_character (dtp, "\r\n", 1, 2, NODELIM);
1811 #else
1812 write_character (dtp, "\n", 1, 1, NODELIM);
1813 #endif
1814 return;
1817 if (is_array_io (dtp))
1819 gfc_offset record;
1820 int finished;
1821 char *p;
1822 int length = dtp->u.p.current_unit->bytes_left;
1824 p = write_block (dtp, length);
1825 if (p == NULL)
1826 return;
1828 if (unlikely (is_char4_unit (dtp)))
1830 gfc_char4_t *p4 = (gfc_char4_t *) p;
1831 memset4 (p4, ' ', length);
1833 else
1834 memset (p, ' ', length);
1836 /* Now that the current record has been padded out,
1837 determine where the next record in the array is. */
1838 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
1839 &finished);
1840 if (finished)
1841 dtp->u.p.current_unit->endfile = AT_ENDFILE;
1842 else
1844 /* Now seek to this record */
1845 record = record * dtp->u.p.current_unit->recl;
1847 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
1849 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
1850 return;
1853 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1856 else
1857 write_character (dtp, " ", 1, 1, NODELIM);
1861 static namelist_info *
1862 nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
1863 namelist_info * base, char * base_name)
1865 int rep_ctr;
1866 int num;
1867 int nml_carry;
1868 int len;
1869 index_type obj_size;
1870 index_type nelem;
1871 size_t dim_i;
1872 size_t clen;
1873 index_type elem_ctr;
1874 size_t obj_name_len;
1875 void * p;
1876 char cup;
1877 char * obj_name;
1878 char * ext_name;
1879 char * q;
1880 size_t ext_name_len;
1881 char rep_buff[NML_DIGITS];
1882 namelist_info * cmp;
1883 namelist_info * retval = obj->next;
1884 size_t base_name_len;
1885 size_t base_var_name_len;
1886 size_t tot_len;
1888 /* Set the character to be used to separate values
1889 to a comma or semi-colon. */
1891 char semi_comma =
1892 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1894 /* Write namelist variable names in upper case. If a derived type,
1895 nothing is output. If a component, base and base_name are set. */
1897 if (obj->type != BT_DERIVED)
1899 namelist_write_newline (dtp);
1900 write_character (dtp, " ", 1, 1, NODELIM);
1902 len = 0;
1903 if (base)
1905 len = strlen (base->var_name);
1906 base_name_len = strlen (base_name);
1907 for (dim_i = 0; dim_i < base_name_len; dim_i++)
1909 cup = toupper ((int) base_name[dim_i]);
1910 write_character (dtp, &cup, 1, 1, NODELIM);
1913 clen = strlen (obj->var_name);
1914 for (dim_i = len; dim_i < clen; dim_i++)
1916 cup = toupper ((int) obj->var_name[dim_i]);
1917 if (cup == '+')
1918 cup = '%';
1919 write_character (dtp, &cup, 1, 1, NODELIM);
1921 write_character (dtp, "=", 1, 1, NODELIM);
1924 /* Counts the number of data output on a line, including names. */
1926 num = 1;
1928 len = obj->len;
1930 switch (obj->type)
1933 case BT_REAL:
1934 obj_size = size_from_real_kind (len);
1935 break;
1937 case BT_COMPLEX:
1938 obj_size = size_from_complex_kind (len);
1939 break;
1941 case BT_CHARACTER:
1942 obj_size = obj->string_length;
1943 break;
1945 default:
1946 obj_size = len;
1949 if (obj->var_rank)
1950 obj_size = obj->size;
1952 /* Set the index vector and count the number of elements. */
1954 nelem = 1;
1955 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1957 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
1958 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
1961 /* Main loop to output the data held in the object. */
1963 rep_ctr = 1;
1964 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
1967 /* Build the pointer to the data value. The offset is passed by
1968 recursive calls to this function for arrays of derived types.
1969 Is NULL otherwise. */
1971 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
1972 p += offset;
1974 /* Check for repeat counts of intrinsic types. */
1976 if ((elem_ctr < (nelem - 1)) &&
1977 (obj->type != BT_DERIVED) &&
1978 !memcmp (p, (void*)(p + obj_size ), obj_size ))
1980 rep_ctr++;
1983 /* Execute a repeated output. Note the flag no_leading_blank that
1984 is used in the functions used to output the intrinsic types. */
1986 else
1988 if (rep_ctr > 1)
1990 snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
1991 write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
1992 dtp->u.p.no_leading_blank = 1;
1994 num++;
1996 /* Output the data, if an intrinsic type, or recurse into this
1997 routine to treat derived types. */
1999 switch (obj->type)
2002 case BT_INTEGER:
2003 write_integer (dtp, p, len);
2004 break;
2006 case BT_LOGICAL:
2007 write_logical (dtp, p, len);
2008 break;
2010 case BT_CHARACTER:
2011 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
2012 write_character (dtp, p, 4, obj->string_length, DELIM);
2013 else
2014 write_character (dtp, p, 1, obj->string_length, DELIM);
2015 break;
2017 case BT_REAL:
2018 write_real (dtp, p, len);
2019 break;
2021 case BT_COMPLEX:
2022 dtp->u.p.no_leading_blank = 0;
2023 num++;
2024 write_complex (dtp, p, len, obj_size);
2025 break;
2027 case BT_DERIVED:
2028 case BT_CLASS:
2029 /* To treat a derived type, we need to build two strings:
2030 ext_name = the name, including qualifiers that prepends
2031 component names in the output - passed to
2032 nml_write_obj.
2033 obj_name = the derived type name with no qualifiers but %
2034 appended. This is used to identify the
2035 components. */
2037 /* First ext_name => get length of all possible components */
2038 if (obj->dtio_sub != NULL)
2040 int unit = dtp->u.p.current_unit->unit_number;
2041 char iotype[] = "NAMELIST";
2042 gfc_charlen_type iotype_len = 8;
2043 char tmp_iomsg[IOMSG_LEN] = "";
2044 char *child_iomsg;
2045 gfc_charlen_type child_iomsg_len;
2046 int noiostat;
2047 int *child_iostat = NULL;
2048 gfc_array_i4 vlist;
2049 gfc_class list_obj;
2050 formatted_dtio dtio_ptr = (formatted_dtio)obj->dtio_sub;
2052 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
2054 list_obj.data = p;
2055 list_obj.vptr = obj->vtable;
2056 list_obj.len = 0;
2058 /* Set iostat, intent(out). */
2059 noiostat = 0;
2060 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
2061 dtp->common.iostat : &noiostat;
2063 /* Set iomsg, intent(inout). */
2064 if (dtp->common.flags & IOPARM_HAS_IOMSG)
2066 child_iomsg = dtp->common.iomsg;
2067 child_iomsg_len = dtp->common.iomsg_len;
2069 else
2071 child_iomsg = tmp_iomsg;
2072 child_iomsg_len = IOMSG_LEN;
2074 namelist_write_newline (dtp);
2075 /* Call the user defined formatted WRITE procedure. */
2076 dtp->u.p.current_unit->child_dtio++;
2077 dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
2078 child_iostat, child_iomsg,
2079 iotype_len, child_iomsg_len);
2080 dtp->u.p.current_unit->child_dtio--;
2082 goto obj_loop;
2085 base_name_len = base_name ? strlen (base_name) : 0;
2086 base_var_name_len = base ? strlen (base->var_name) : 0;
2087 ext_name_len = base_name_len + base_var_name_len
2088 + strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
2089 ext_name = xmalloc (ext_name_len);
2091 if (base_name)
2092 memcpy (ext_name, base_name, base_name_len);
2093 clen = strlen (obj->var_name + base_var_name_len);
2094 memcpy (ext_name + base_name_len,
2095 obj->var_name + base_var_name_len, clen);
2097 /* Append the qualifier. */
2099 tot_len = base_name_len + clen;
2100 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
2102 if (!dim_i)
2104 ext_name[tot_len] = '(';
2105 tot_len++;
2107 snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
2108 (int) obj->ls[dim_i].idx);
2109 tot_len += strlen (ext_name + tot_len);
2110 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
2111 tot_len++;
2114 ext_name[tot_len] = '\0';
2115 for (q = ext_name; *q; q++)
2116 if (*q == '+')
2117 *q = '%';
2119 /* Now obj_name. */
2121 obj_name_len = strlen (obj->var_name) + 1;
2122 obj_name = xmalloc (obj_name_len + 1);
2123 memcpy (obj_name, obj->var_name, obj_name_len-1);
2124 memcpy (obj_name + obj_name_len-1, "%", 2);
2126 /* Now loop over the components. Update the component pointer
2127 with the return value from nml_write_obj => this loop jumps
2128 past nested derived types. */
2130 for (cmp = obj->next;
2131 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
2132 cmp = retval)
2134 retval = nml_write_obj (dtp, cmp,
2135 (index_type)(p - obj->mem_pos),
2136 obj, ext_name);
2139 free (obj_name);
2140 free (ext_name);
2141 goto obj_loop;
2143 default:
2144 internal_error (&dtp->common, "Bad type for namelist write");
2147 /* Reset the leading blank suppression, write a comma (or semi-colon)
2148 and, if 5 values have been output, write a newline and advance
2149 to column 2. Reset the repeat counter. */
2151 dtp->u.p.no_leading_blank = 0;
2152 if (obj->type == BT_CHARACTER)
2154 if (dtp->u.p.nml_delim != '\0')
2155 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2157 else
2158 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2159 if (num > 5)
2161 num = 0;
2162 if (dtp->u.p.nml_delim == '\0')
2163 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2164 namelist_write_newline (dtp);
2165 write_character (dtp, " ", 1, 1, NODELIM);
2167 rep_ctr = 1;
2170 /* Cycle through and increment the index vector. */
2172 obj_loop:
2174 nml_carry = 1;
2175 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
2177 obj->ls[dim_i].idx += nml_carry ;
2178 nml_carry = 0;
2179 if (obj->ls[dim_i].idx > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
2181 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
2182 nml_carry = 1;
2187 /* Return a pointer beyond the furthest object accessed. */
2189 return retval;
2193 /* This is the entry function for namelist writes. It outputs the name
2194 of the namelist and iterates through the namelist by calls to
2195 nml_write_obj. The call below has dummys in the arguments used in
2196 the treatment of derived types. */
2198 void
2199 namelist_write (st_parameter_dt *dtp)
2201 namelist_info * t1, *t2, *dummy = NULL;
2202 index_type i;
2203 index_type dummy_offset = 0;
2204 char c;
2205 char * dummy_name = NULL;
2207 /* Set the delimiter for namelist output. */
2208 switch (dtp->u.p.current_unit->delim_status)
2210 case DELIM_APOSTROPHE:
2211 dtp->u.p.nml_delim = '\'';
2212 break;
2213 case DELIM_QUOTE:
2214 case DELIM_UNSPECIFIED:
2215 dtp->u.p.nml_delim = '"';
2216 break;
2217 default:
2218 dtp->u.p.nml_delim = '\0';
2221 write_character (dtp, "&", 1, 1, NODELIM);
2223 /* Write namelist name in upper case - f95 std. */
2224 for (i = 0 ;i < dtp->namelist_name_len ;i++ )
2226 c = toupper ((int) dtp->namelist_name[i]);
2227 write_character (dtp, &c, 1 ,1, NODELIM);
2230 if (dtp->u.p.ionml != NULL)
2232 t1 = dtp->u.p.ionml;
2233 while (t1 != NULL)
2235 t2 = t1;
2236 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
2240 namelist_write_newline (dtp);
2241 write_character (dtp, " /", 1, 2, NODELIM);
2244 #undef NML_DIGITS