t-linux64 (MULTILIB_OSDIRNAMES): Use x86_64-linux-gnux32 as multiarch name for x32.
[official-gcc.git] / libgfortran / io / write.c
blob838bc0d6688fb15aa54520ef9751aa090d3b707f
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2 2012
3 Free Software Foundation, Inc.
4 Contributed by Andy Vaught
5 Namelist output contributed by Paul Thomas
6 F2003 I/O support contributed by Jerry DeLisle
8 This file is part of the GNU Fortran runtime library (libgfortran).
10 Libgfortran is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
15 Libgfortran is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 Under Section 7 of GPL version 3, you are granted additional
21 permissions described in the GCC Runtime Library Exception, version
22 3.1, as published by the Free Software Foundation.
24 You should have received a copy of the GNU General Public License and
25 a copy of the GCC Runtime Library Exception along with this program;
26 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
27 <http://www.gnu.org/licenses/>. */
29 #include "io.h"
30 #include "format.h"
31 #include "unix.h"
32 #include <assert.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <stdbool.h>
37 #include <errno.h>
38 #define star_fill(p, n) memset(p, '*', n)
40 typedef unsigned char uchar;
42 /* Helper functions for character(kind=4) internal units. These are needed
43 by write_float.def. */
45 static void
46 memcpy4 (gfc_char4_t *dest, const char *source, int k)
48 int j;
50 const char *p = source;
51 for (j = 0; j < k; j++)
52 *dest++ = (gfc_char4_t) *p++;
55 /* This include contains the heart and soul of formatted floating point. */
56 #include "write_float.def"
58 /* Write out default char4. */
60 static void
61 write_default_char4 (st_parameter_dt *dtp, const gfc_char4_t *source,
62 int src_len, int w_len)
64 char *p;
65 int j, k = 0;
66 gfc_char4_t c;
67 uchar d;
69 /* Take care of preceding blanks. */
70 if (w_len > src_len)
72 k = w_len - src_len;
73 p = write_block (dtp, k);
74 if (p == NULL)
75 return;
76 if (is_char4_unit (dtp))
78 gfc_char4_t *p4 = (gfc_char4_t *) p;
79 memset4 (p4, ' ', k);
81 else
82 memset (p, ' ', k);
85 /* Get ready to handle delimiters if needed. */
86 switch (dtp->u.p.current_unit->delim_status)
88 case DELIM_APOSTROPHE:
89 d = '\'';
90 break;
91 case DELIM_QUOTE:
92 d = '"';
93 break;
94 default:
95 d = ' ';
96 break;
99 /* Now process the remaining characters, one at a time. */
100 for (j = 0; j < src_len; j++)
102 c = source[j];
103 if (is_char4_unit (dtp))
105 gfc_char4_t *q;
106 /* Handle delimiters if any. */
107 if (c == d && d != ' ')
109 p = write_block (dtp, 2);
110 if (p == NULL)
111 return;
112 q = (gfc_char4_t *) p;
113 *q++ = c;
115 else
117 p = write_block (dtp, 1);
118 if (p == NULL)
119 return;
120 q = (gfc_char4_t *) p;
122 *q = c;
124 else
126 /* Handle delimiters if any. */
127 if (c == d && d != ' ')
129 p = write_block (dtp, 2);
130 if (p == NULL)
131 return;
132 *p++ = (uchar) c;
134 else
136 p = write_block (dtp, 1);
137 if (p == NULL)
138 return;
140 *p = c > 255 ? '?' : (uchar) c;
146 /* Write out UTF-8 converted from char4. */
148 static void
149 write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
150 int src_len, int w_len)
152 char *p;
153 int j, k = 0;
154 gfc_char4_t c;
155 static const uchar masks[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
156 static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
157 int nbytes;
158 uchar buf[6], d, *q;
160 /* Take care of preceding blanks. */
161 if (w_len > src_len)
163 k = w_len - src_len;
164 p = write_block (dtp, k);
165 if (p == NULL)
166 return;
167 memset (p, ' ', k);
170 /* Get ready to handle delimiters if needed. */
171 switch (dtp->u.p.current_unit->delim_status)
173 case DELIM_APOSTROPHE:
174 d = '\'';
175 break;
176 case DELIM_QUOTE:
177 d = '"';
178 break;
179 default:
180 d = ' ';
181 break;
184 /* Now process the remaining characters, one at a time. */
185 for (j = k; j < src_len; j++)
187 c = source[j];
188 if (c < 0x80)
190 /* Handle the delimiters if any. */
191 if (c == d && d != ' ')
193 p = write_block (dtp, 2);
194 if (p == NULL)
195 return;
196 *p++ = (uchar) c;
198 else
200 p = write_block (dtp, 1);
201 if (p == NULL)
202 return;
204 *p = (uchar) c;
206 else
208 /* Convert to UTF-8 sequence. */
209 nbytes = 1;
210 q = &buf[6];
214 *--q = ((c & 0x3F) | 0x80);
215 c >>= 6;
216 nbytes++;
218 while (c >= 0x3F || (c & limits[nbytes-1]));
220 *--q = (c | masks[nbytes-1]);
222 p = write_block (dtp, nbytes);
223 if (p == NULL)
224 return;
226 while (q < &buf[6])
227 *p++ = *q++;
233 void
234 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
236 int wlen;
237 char *p;
239 wlen = f->u.string.length < 0
240 || (f->format == FMT_G && f->u.string.length == 0)
241 ? len : f->u.string.length;
243 #ifdef HAVE_CRLF
244 /* If this is formatted STREAM IO convert any embedded line feed characters
245 to CR_LF on systems that use that sequence for newlines. See F2003
246 Standard sections 10.6.3 and 9.9 for further information. */
247 if (is_stream_io (dtp))
249 const char crlf[] = "\r\n";
250 int i, q, bytes;
251 q = bytes = 0;
253 /* Write out any padding if needed. */
254 if (len < wlen)
256 p = write_block (dtp, wlen - len);
257 if (p == NULL)
258 return;
259 memset (p, ' ', wlen - len);
262 /* Scan the source string looking for '\n' and convert it if found. */
263 for (i = 0; i < wlen; i++)
265 if (source[i] == '\n')
267 /* Write out the previously scanned characters in the string. */
268 if (bytes > 0)
270 p = write_block (dtp, bytes);
271 if (p == NULL)
272 return;
273 memcpy (p, &source[q], bytes);
274 q += bytes;
275 bytes = 0;
278 /* Write out the CR_LF sequence. */
279 q++;
280 p = write_block (dtp, 2);
281 if (p == NULL)
282 return;
283 memcpy (p, crlf, 2);
285 else
286 bytes++;
289 /* Write out any remaining bytes if no LF was found. */
290 if (bytes > 0)
292 p = write_block (dtp, bytes);
293 if (p == NULL)
294 return;
295 memcpy (p, &source[q], bytes);
298 else
300 #endif
301 p = write_block (dtp, wlen);
302 if (p == NULL)
303 return;
305 if (unlikely (is_char4_unit (dtp)))
307 gfc_char4_t *p4 = (gfc_char4_t *) p;
308 if (wlen < len)
309 memcpy4 (p4, source, wlen);
310 else
312 memset4 (p4, ' ', wlen - len);
313 memcpy4 (p4 + wlen - len, source, len);
315 return;
318 if (wlen < len)
319 memcpy (p, source, wlen);
320 else
322 memset (p, ' ', wlen - len);
323 memcpy (p + wlen - len, source, len);
325 #ifdef HAVE_CRLF
327 #endif
331 /* The primary difference between write_a_char4 and write_a is that we have to
332 deal with writing from the first byte of the 4-byte character and pay
333 attention to the most significant bytes. For ENCODING="default" write the
334 lowest significant byte. If the 3 most significant bytes contain
335 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
336 to the UTF-8 encoded string before writing out. */
338 void
339 write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
341 int wlen;
342 gfc_char4_t *q;
344 wlen = f->u.string.length < 0
345 || (f->format == FMT_G && f->u.string.length == 0)
346 ? len : f->u.string.length;
348 q = (gfc_char4_t *) source;
349 #ifdef HAVE_CRLF
350 /* If this is formatted STREAM IO convert any embedded line feed characters
351 to CR_LF on systems that use that sequence for newlines. See F2003
352 Standard sections 10.6.3 and 9.9 for further information. */
353 if (is_stream_io (dtp))
355 const gfc_char4_t crlf[] = {0x000d,0x000a};
356 int i, bytes;
357 gfc_char4_t *qq;
358 bytes = 0;
360 /* Write out any padding if needed. */
361 if (len < wlen)
363 char *p;
364 p = write_block (dtp, wlen - len);
365 if (p == NULL)
366 return;
367 memset (p, ' ', wlen - len);
370 /* Scan the source string looking for '\n' and convert it if found. */
371 qq = (gfc_char4_t *) source;
372 for (i = 0; i < wlen; i++)
374 if (qq[i] == '\n')
376 /* Write out the previously scanned characters in the string. */
377 if (bytes > 0)
379 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
380 write_utf8_char4 (dtp, q, bytes, 0);
381 else
382 write_default_char4 (dtp, q, bytes, 0);
383 bytes = 0;
386 /* Write out the CR_LF sequence. */
387 write_default_char4 (dtp, crlf, 2, 0);
389 else
390 bytes++;
393 /* Write out any remaining bytes if no LF was found. */
394 if (bytes > 0)
396 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
397 write_utf8_char4 (dtp, q, bytes, 0);
398 else
399 write_default_char4 (dtp, q, bytes, 0);
402 else
404 #endif
405 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
406 write_utf8_char4 (dtp, q, len, wlen);
407 else
408 write_default_char4 (dtp, q, len, wlen);
409 #ifdef HAVE_CRLF
411 #endif
415 static GFC_INTEGER_LARGEST
416 extract_int (const void *p, int len)
418 GFC_INTEGER_LARGEST i = 0;
420 if (p == NULL)
421 return i;
423 switch (len)
425 case 1:
427 GFC_INTEGER_1 tmp;
428 memcpy ((void *) &tmp, p, len);
429 i = tmp;
431 break;
432 case 2:
434 GFC_INTEGER_2 tmp;
435 memcpy ((void *) &tmp, p, len);
436 i = tmp;
438 break;
439 case 4:
441 GFC_INTEGER_4 tmp;
442 memcpy ((void *) &tmp, p, len);
443 i = tmp;
445 break;
446 case 8:
448 GFC_INTEGER_8 tmp;
449 memcpy ((void *) &tmp, p, len);
450 i = tmp;
452 break;
453 #ifdef HAVE_GFC_INTEGER_16
454 case 16:
456 GFC_INTEGER_16 tmp;
457 memcpy ((void *) &tmp, p, len);
458 i = tmp;
460 break;
461 #endif
462 default:
463 internal_error (NULL, "bad integer kind");
466 return i;
469 static GFC_UINTEGER_LARGEST
470 extract_uint (const void *p, int len)
472 GFC_UINTEGER_LARGEST i = 0;
474 if (p == NULL)
475 return i;
477 switch (len)
479 case 1:
481 GFC_INTEGER_1 tmp;
482 memcpy ((void *) &tmp, p, len);
483 i = (GFC_UINTEGER_1) tmp;
485 break;
486 case 2:
488 GFC_INTEGER_2 tmp;
489 memcpy ((void *) &tmp, p, len);
490 i = (GFC_UINTEGER_2) tmp;
492 break;
493 case 4:
495 GFC_INTEGER_4 tmp;
496 memcpy ((void *) &tmp, p, len);
497 i = (GFC_UINTEGER_4) tmp;
499 break;
500 case 8:
502 GFC_INTEGER_8 tmp;
503 memcpy ((void *) &tmp, p, len);
504 i = (GFC_UINTEGER_8) tmp;
506 break;
507 #ifdef HAVE_GFC_INTEGER_16
508 case 10:
509 case 16:
511 GFC_INTEGER_16 tmp = 0;
512 memcpy ((void *) &tmp, p, len);
513 i = (GFC_UINTEGER_16) tmp;
515 break;
516 #endif
517 default:
518 internal_error (NULL, "bad integer kind");
521 return i;
525 void
526 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
528 char *p;
529 int wlen;
530 GFC_INTEGER_LARGEST n;
532 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
534 p = write_block (dtp, wlen);
535 if (p == NULL)
536 return;
538 n = extract_int (source, len);
540 if (unlikely (is_char4_unit (dtp)))
542 gfc_char4_t *p4 = (gfc_char4_t *) p;
543 memset4 (p4, ' ', wlen -1);
544 p4[wlen - 1] = (n) ? 'T' : 'F';
545 return;
548 memset (p, ' ', wlen -1);
549 p[wlen - 1] = (n) ? 'T' : 'F';
553 static void
554 write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
556 int w, m, digits, nzero, nblank;
557 char *p;
559 w = f->u.integer.w;
560 m = f->u.integer.m;
562 /* Special case: */
564 if (m == 0 && n == 0)
566 if (w == 0)
567 w = 1;
569 p = write_block (dtp, w);
570 if (p == NULL)
571 return;
572 if (unlikely (is_char4_unit (dtp)))
574 gfc_char4_t *p4 = (gfc_char4_t *) p;
575 memset4 (p4, ' ', w);
577 else
578 memset (p, ' ', w);
579 goto done;
582 digits = strlen (q);
584 /* Select a width if none was specified. The idea here is to always
585 print something. */
587 if (w == 0)
588 w = ((digits < m) ? m : digits);
590 p = write_block (dtp, w);
591 if (p == NULL)
592 return;
594 nzero = 0;
595 if (digits < m)
596 nzero = m - digits;
598 /* See if things will work. */
600 nblank = w - (nzero + digits);
602 if (unlikely (is_char4_unit (dtp)))
604 gfc_char4_t *p4 = (gfc_char4_t *) p;
605 if (nblank < 0)
607 memset4 (p4, '*', w);
608 return;
611 if (!dtp->u.p.no_leading_blank)
613 memset4 (p4, ' ', nblank);
614 q += nblank;
615 memset4 (p4, '0', nzero);
616 q += nzero;
617 memcpy4 (p4, q, digits);
619 else
621 memset4 (p4, '0', nzero);
622 q += nzero;
623 memcpy4 (p4, q, digits);
624 q += digits;
625 memset4 (p4, ' ', nblank);
626 dtp->u.p.no_leading_blank = 0;
628 return;
631 if (nblank < 0)
633 star_fill (p, w);
634 goto done;
637 if (!dtp->u.p.no_leading_blank)
639 memset (p, ' ', nblank);
640 p += nblank;
641 memset (p, '0', nzero);
642 p += nzero;
643 memcpy (p, q, digits);
645 else
647 memset (p, '0', nzero);
648 p += nzero;
649 memcpy (p, q, digits);
650 p += digits;
651 memset (p, ' ', nblank);
652 dtp->u.p.no_leading_blank = 0;
655 done:
656 return;
659 static void
660 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
661 int len,
662 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
664 GFC_INTEGER_LARGEST n = 0;
665 int w, m, digits, nsign, nzero, nblank;
666 char *p;
667 const char *q;
668 sign_t sign;
669 char itoa_buf[GFC_BTOA_BUF_SIZE];
671 w = f->u.integer.w;
672 m = f->format == FMT_G ? -1 : f->u.integer.m;
674 n = extract_int (source, len);
676 /* Special case: */
677 if (m == 0 && n == 0)
679 if (w == 0)
680 w = 1;
682 p = write_block (dtp, w);
683 if (p == NULL)
684 return;
685 if (unlikely (is_char4_unit (dtp)))
687 gfc_char4_t *p4 = (gfc_char4_t *) p;
688 memset4 (p4, ' ', w);
690 else
691 memset (p, ' ', w);
692 goto done;
695 sign = calculate_sign (dtp, n < 0);
696 if (n < 0)
697 n = -n;
698 nsign = sign == S_NONE ? 0 : 1;
700 /* conv calls itoa which sets the negative sign needed
701 by write_integer. The sign '+' or '-' is set below based on sign
702 calculated above, so we just point past the sign in the string
703 before proceeding to avoid double signs in corner cases.
704 (see PR38504) */
705 q = conv (n, itoa_buf, sizeof (itoa_buf));
706 if (*q == '-')
707 q++;
709 digits = strlen (q);
711 /* Select a width if none was specified. The idea here is to always
712 print something. */
714 if (w == 0)
715 w = ((digits < m) ? m : digits) + nsign;
717 p = write_block (dtp, w);
718 if (p == NULL)
719 return;
721 nzero = 0;
722 if (digits < m)
723 nzero = m - digits;
725 /* See if things will work. */
727 nblank = w - (nsign + nzero + digits);
729 if (unlikely (is_char4_unit (dtp)))
731 gfc_char4_t * p4 = (gfc_char4_t *) p;
732 if (nblank < 0)
734 memset4 (p4, '*', w);
735 goto done;
738 memset4 (p4, ' ', nblank);
739 p4 += nblank;
741 switch (sign)
743 case S_PLUS:
744 *p4++ = '+';
745 break;
746 case S_MINUS:
747 *p4++ = '-';
748 break;
749 case S_NONE:
750 break;
753 memset4 (p4, '0', nzero);
754 p4 += nzero;
756 memcpy4 (p4, q, digits);
757 return;
760 if (nblank < 0)
762 star_fill (p, w);
763 goto done;
766 memset (p, ' ', nblank);
767 p += nblank;
769 switch (sign)
771 case S_PLUS:
772 *p++ = '+';
773 break;
774 case S_MINUS:
775 *p++ = '-';
776 break;
777 case S_NONE:
778 break;
781 memset (p, '0', nzero);
782 p += nzero;
784 memcpy (p, q, digits);
786 done:
787 return;
791 /* Convert unsigned octal to ascii. */
793 static const char *
794 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
796 char *p;
798 assert (len >= GFC_OTOA_BUF_SIZE);
800 if (n == 0)
801 return "0";
803 p = buffer + GFC_OTOA_BUF_SIZE - 1;
804 *p = '\0';
806 while (n != 0)
808 *--p = '0' + (n & 7);
809 n >>= 3;
812 return p;
816 /* Convert unsigned binary to ascii. */
818 static const char *
819 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
821 char *p;
823 assert (len >= GFC_BTOA_BUF_SIZE);
825 if (n == 0)
826 return "0";
828 p = buffer + GFC_BTOA_BUF_SIZE - 1;
829 *p = '\0';
831 while (n != 0)
833 *--p = '0' + (n & 1);
834 n >>= 1;
837 return p;
840 /* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
841 to convert large reals with kind sizes that exceed the largest integer type
842 available on certain platforms. In these cases, byte by byte conversion is
843 performed. Endianess is taken into account. */
845 /* Conversion to binary. */
847 static const char *
848 btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
850 char *q;
851 int i, j;
853 q = buffer;
854 if (big_endian)
856 const char *p = s;
857 for (i = 0; i < len; i++)
859 char c = *p;
861 /* Test for zero. Needed by write_boz later. */
862 if (*p != 0)
863 *n = 1;
865 for (j = 0; j < 8; j++)
867 *q++ = (c & 128) ? '1' : '0';
868 c <<= 1;
870 p++;
873 else
875 const char *p = s + len - 1;
876 for (i = 0; i < len; i++)
878 char c = *p;
880 /* Test for zero. Needed by write_boz later. */
881 if (*p != 0)
882 *n = 1;
884 for (j = 0; j < 8; j++)
886 *q++ = (c & 128) ? '1' : '0';
887 c <<= 1;
889 p--;
893 *q = '\0';
895 if (*n == 0)
896 return "0";
898 /* Move past any leading zeros. */
899 while (*buffer == '0')
900 buffer++;
902 return buffer;
906 /* Conversion to octal. */
908 static const char *
909 otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
911 char *q;
912 int i, j, k;
913 uint8_t octet;
915 q = buffer + GFC_OTOA_BUF_SIZE - 1;
916 *q = '\0';
917 i = k = octet = 0;
919 if (big_endian)
921 const char *p = s + len - 1;
922 char c = *p;
923 while (i < len)
925 /* Test for zero. Needed by write_boz later. */
926 if (*p != 0)
927 *n = 1;
929 for (j = 0; j < 3 && i < len; j++)
931 octet |= (c & 1) << j;
932 c >>= 1;
933 if (++k > 7)
935 i++;
936 k = 0;
937 c = *--p;
940 *--q = '0' + octet;
941 octet = 0;
944 else
946 const char *p = s;
947 char c = *p;
948 while (i < len)
950 /* Test for zero. Needed by write_boz later. */
951 if (*p != 0)
952 *n = 1;
954 for (j = 0; j < 3 && i < len; j++)
956 octet |= (c & 1) << j;
957 c >>= 1;
958 if (++k > 7)
960 i++;
961 k = 0;
962 c = *++p;
965 *--q = '0' + octet;
966 octet = 0;
970 if (*n == 0)
971 return "0";
973 /* Move past any leading zeros. */
974 while (*q == '0')
975 q++;
977 return q;
980 /* Conversion to hexidecimal. */
982 static const char *
983 ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
985 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
986 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
988 char *q;
989 uint8_t h, l;
990 int i;
992 q = buffer;
994 if (big_endian)
996 const char *p = s;
997 for (i = 0; i < len; i++)
999 /* Test for zero. Needed by write_boz later. */
1000 if (*p != 0)
1001 *n = 1;
1003 h = (*p >> 4) & 0x0F;
1004 l = *p++ & 0x0F;
1005 *q++ = a[h];
1006 *q++ = a[l];
1009 else
1011 const char *p = s + len - 1;
1012 for (i = 0; i < len; i++)
1014 /* Test for zero. Needed by write_boz later. */
1015 if (*p != 0)
1016 *n = 1;
1018 h = (*p >> 4) & 0x0F;
1019 l = *p-- & 0x0F;
1020 *q++ = a[h];
1021 *q++ = a[l];
1025 *q = '\0';
1027 if (*n == 0)
1028 return "0";
1030 /* Move past any leading zeros. */
1031 while (*buffer == '0')
1032 buffer++;
1034 return buffer;
1037 /* gfc_itoa()-- Integer to decimal conversion.
1038 The itoa function is a widespread non-standard extension to standard
1039 C, often declared in <stdlib.h>. Even though the itoa defined here
1040 is a static function we take care not to conflict with any prior
1041 non-static declaration. Hence the 'gfc_' prefix, which is normally
1042 reserved for functions with external linkage. */
1044 static const char *
1045 gfc_itoa (GFC_INTEGER_LARGEST n, char *buffer, size_t len)
1047 int negative;
1048 char *p;
1049 GFC_UINTEGER_LARGEST t;
1051 assert (len >= GFC_ITOA_BUF_SIZE);
1053 if (n == 0)
1054 return "0";
1056 negative = 0;
1057 t = n;
1058 if (n < 0)
1060 negative = 1;
1061 t = -n; /*must use unsigned to protect from overflow*/
1064 p = buffer + GFC_ITOA_BUF_SIZE - 1;
1065 *p = '\0';
1067 while (t != 0)
1069 *--p = '0' + (t % 10);
1070 t /= 10;
1073 if (negative)
1074 *--p = '-';
1075 return p;
1079 void
1080 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1082 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
1086 void
1087 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1089 const char *p;
1090 char itoa_buf[GFC_BTOA_BUF_SIZE];
1091 GFC_UINTEGER_LARGEST n = 0;
1093 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1095 p = btoa_big (source, itoa_buf, len, &n);
1096 write_boz (dtp, f, p, n);
1098 else
1100 n = extract_uint (source, len);
1101 p = btoa (n, itoa_buf, sizeof (itoa_buf));
1102 write_boz (dtp, f, p, n);
1107 void
1108 write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1110 const char *p;
1111 char itoa_buf[GFC_OTOA_BUF_SIZE];
1112 GFC_UINTEGER_LARGEST n = 0;
1114 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1116 p = otoa_big (source, itoa_buf, len, &n);
1117 write_boz (dtp, f, p, n);
1119 else
1121 n = extract_uint (source, len);
1122 p = otoa (n, itoa_buf, sizeof (itoa_buf));
1123 write_boz (dtp, f, p, n);
1127 void
1128 write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1130 const char *p;
1131 char itoa_buf[GFC_XTOA_BUF_SIZE];
1132 GFC_UINTEGER_LARGEST n = 0;
1134 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1136 p = ztoa_big (source, itoa_buf, len, &n);
1137 write_boz (dtp, f, p, n);
1139 else
1141 n = extract_uint (source, len);
1142 p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
1143 write_boz (dtp, f, p, n);
1148 void
1149 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1151 write_float (dtp, f, p, len, 0);
1155 void
1156 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1158 write_float (dtp, f, p, len, 0);
1162 void
1163 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1165 write_float (dtp, f, p, len, 0);
1169 void
1170 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1172 write_float (dtp, f, p, len, 0);
1176 void
1177 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1179 write_float (dtp, f, p, len, 0);
1183 /* Take care of the X/TR descriptor. */
1185 void
1186 write_x (st_parameter_dt *dtp, int len, int nspaces)
1188 char *p;
1190 p = write_block (dtp, len);
1191 if (p == NULL)
1192 return;
1193 if (nspaces > 0 && len - nspaces >= 0)
1195 if (unlikely (is_char4_unit (dtp)))
1197 gfc_char4_t *p4 = (gfc_char4_t *) p;
1198 memset4 (&p4[len - nspaces], ' ', nspaces);
1200 else
1201 memset (&p[len - nspaces], ' ', nspaces);
1206 /* List-directed writing. */
1209 /* Write a single character to the output. Returns nonzero if
1210 something goes wrong. */
1212 static int
1213 write_char (st_parameter_dt *dtp, int c)
1215 char *p;
1217 p = write_block (dtp, 1);
1218 if (p == NULL)
1219 return 1;
1220 if (unlikely (is_char4_unit (dtp)))
1222 gfc_char4_t *p4 = (gfc_char4_t *) p;
1223 *p4 = c;
1224 return 0;
1227 *p = (uchar) c;
1229 return 0;
1233 /* Write a list-directed logical value. */
1235 static void
1236 write_logical (st_parameter_dt *dtp, const char *source, int length)
1238 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
1242 /* Write a list-directed integer value. */
1244 static void
1245 write_integer (st_parameter_dt *dtp, const char *source, int length)
1247 char *p;
1248 const char *q;
1249 int digits;
1250 int width;
1251 char itoa_buf[GFC_ITOA_BUF_SIZE];
1253 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1255 switch (length)
1257 case 1:
1258 width = 4;
1259 break;
1261 case 2:
1262 width = 6;
1263 break;
1265 case 4:
1266 width = 11;
1267 break;
1269 case 8:
1270 width = 20;
1271 break;
1273 default:
1274 width = 0;
1275 break;
1278 digits = strlen (q);
1280 if (width < digits)
1281 width = digits;
1282 p = write_block (dtp, width);
1283 if (p == NULL)
1284 return;
1286 if (unlikely (is_char4_unit (dtp)))
1288 gfc_char4_t *p4 = (gfc_char4_t *) p;
1289 if (dtp->u.p.no_leading_blank)
1291 memcpy4 (p4, q, digits);
1292 memset4 (p4 + digits, ' ', width - digits);
1294 else
1296 memset4 (p4, ' ', width - digits);
1297 memcpy4 (p4 + width - digits, q, digits);
1299 return;
1302 if (dtp->u.p.no_leading_blank)
1304 memcpy (p, q, digits);
1305 memset (p + digits, ' ', width - digits);
1307 else
1309 memset (p, ' ', width - digits);
1310 memcpy (p + width - digits, q, digits);
1315 /* Write a list-directed string. We have to worry about delimiting
1316 the strings if the file has been opened in that mode. */
1318 static void
1319 write_character (st_parameter_dt *dtp, const char *source, int kind, int length)
1321 int i, extra;
1322 char *p, d;
1324 switch (dtp->u.p.current_unit->delim_status)
1326 case DELIM_APOSTROPHE:
1327 d = '\'';
1328 break;
1329 case DELIM_QUOTE:
1330 d = '"';
1331 break;
1332 default:
1333 d = ' ';
1334 break;
1337 if (kind == 1)
1339 if (d == ' ')
1340 extra = 0;
1341 else
1343 extra = 2;
1345 for (i = 0; i < length; i++)
1346 if (source[i] == d)
1347 extra++;
1350 p = write_block (dtp, length + extra);
1351 if (p == NULL)
1352 return;
1354 if (unlikely (is_char4_unit (dtp)))
1356 gfc_char4_t d4 = (gfc_char4_t) d;
1357 gfc_char4_t *p4 = (gfc_char4_t *) p;
1359 if (d4 == ' ')
1360 memcpy4 (p4, source, length);
1361 else
1363 *p4++ = d4;
1365 for (i = 0; i < length; i++)
1367 *p4++ = (gfc_char4_t) source[i];
1368 if (source[i] == d)
1369 *p4++ = d4;
1372 *p4 = d4;
1374 return;
1377 if (d == ' ')
1378 memcpy (p, source, length);
1379 else
1381 *p++ = d;
1383 for (i = 0; i < length; i++)
1385 *p++ = source[i];
1386 if (source[i] == d)
1387 *p++ = d;
1390 *p = d;
1393 else
1395 if (d == ' ')
1397 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1398 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1399 else
1400 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1402 else
1404 p = write_block (dtp, 1);
1405 *p = d;
1407 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1408 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1409 else
1410 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1412 p = write_block (dtp, 1);
1413 *p = d;
1419 /* Set an fnode to default format. */
1421 static void
1422 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
1424 f->format = FMT_G;
1425 switch (length)
1427 case 4:
1428 f->u.real.w = 16;
1429 f->u.real.d = 9;
1430 f->u.real.e = 2;
1431 break;
1432 case 8:
1433 f->u.real.w = 25;
1434 f->u.real.d = 17;
1435 f->u.real.e = 3;
1436 break;
1437 case 10:
1438 f->u.real.w = 30;
1439 f->u.real.d = 21;
1440 f->u.real.e = 4;
1441 break;
1442 case 16:
1443 f->u.real.w = 45;
1444 f->u.real.d = 36;
1445 f->u.real.e = 4;
1446 break;
1447 default:
1448 internal_error (&dtp->common, "bad real kind");
1449 break;
1453 /* Output a real number with default format. To guarantee that a
1454 binary -> decimal -> binary roundtrip conversion recovers the
1455 original value, IEEE 754-2008 requires 9, 17, 21 and 36 significant
1456 digits for REAL kinds 4, 8, 10, and 16, respectively. Thus, we use
1457 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4 for
1458 REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
1459 Fortran standard requires outputting an extra digit when the scale
1460 factor is 1 and when the magnitude of the value is such that E
1461 editing is used. However, gfortran compensates for this, and thus
1462 for list formatted the same number of significant digits is
1463 generated both when using F and E editing. */
1465 void
1466 write_real (st_parameter_dt *dtp, const char *source, int length)
1468 fnode f ;
1469 int org_scale = dtp->u.p.scale_factor;
1470 dtp->u.p.scale_factor = 1;
1471 set_fnode_default (dtp, &f, length);
1472 write_float (dtp, &f, source , length, 1);
1473 dtp->u.p.scale_factor = org_scale;
1476 /* Similar to list formatted REAL output, for kPG0 where k > 0 we
1477 compensate for the extra digit. */
1479 void
1480 write_real_g0 (st_parameter_dt *dtp, const char *source, int length, int d)
1482 fnode f;
1483 int comp_d;
1484 set_fnode_default (dtp, &f, length);
1485 if (d > 0)
1486 f.u.real.d = d;
1488 /* Compensate for extra digits when using scale factor, d is not
1489 specified, and the magnitude is such that E editing is used. */
1490 if (dtp->u.p.scale_factor > 0 && d == 0)
1491 comp_d = 1;
1492 else
1493 comp_d = 0;
1494 dtp->u.p.g0_no_blanks = 1;
1495 write_float (dtp, &f, source , length, comp_d);
1496 dtp->u.p.g0_no_blanks = 0;
1500 static void
1501 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1503 char semi_comma =
1504 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1506 if (write_char (dtp, '('))
1507 return;
1508 write_real (dtp, source, kind);
1510 if (write_char (dtp, semi_comma))
1511 return;
1512 write_real (dtp, source + size / 2, kind);
1514 write_char (dtp, ')');
1518 /* Write the separator between items. */
1520 static void
1521 write_separator (st_parameter_dt *dtp)
1523 char *p;
1525 p = write_block (dtp, options.separator_len);
1526 if (p == NULL)
1527 return;
1528 if (unlikely (is_char4_unit (dtp)))
1530 gfc_char4_t *p4 = (gfc_char4_t *) p;
1531 memcpy4 (p4, options.separator, options.separator_len);
1533 else
1534 memcpy (p, options.separator, options.separator_len);
1538 /* Write an item with list formatting.
1539 TODO: handle skipping to the next record correctly, particularly
1540 with strings. */
1542 static void
1543 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1544 size_t size)
1546 if (dtp->u.p.current_unit == NULL)
1547 return;
1549 if (dtp->u.p.first_item)
1551 dtp->u.p.first_item = 0;
1552 write_char (dtp, ' ');
1554 else
1556 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1557 dtp->u.p.current_unit->delim_status != DELIM_NONE)
1558 write_separator (dtp);
1561 switch (type)
1563 case BT_INTEGER:
1564 write_integer (dtp, p, kind);
1565 break;
1566 case BT_LOGICAL:
1567 write_logical (dtp, p, kind);
1568 break;
1569 case BT_CHARACTER:
1570 write_character (dtp, p, kind, size);
1571 break;
1572 case BT_REAL:
1573 write_real (dtp, p, kind);
1574 break;
1575 case BT_COMPLEX:
1576 write_complex (dtp, p, kind, size);
1577 break;
1578 default:
1579 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1582 dtp->u.p.char_flag = (type == BT_CHARACTER);
1586 void
1587 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1588 size_t size, size_t nelems)
1590 size_t elem;
1591 char *tmp;
1592 size_t stride = type == BT_CHARACTER ?
1593 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1595 tmp = (char *) p;
1597 /* Big loop over all the elements. */
1598 for (elem = 0; elem < nelems; elem++)
1600 dtp->u.p.item_count++;
1601 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
1605 /* NAMELIST OUTPUT
1607 nml_write_obj writes a namelist object to the output stream. It is called
1608 recursively for derived type components:
1609 obj = is the namelist_info for the current object.
1610 offset = the offset relative to the address held by the object for
1611 derived type arrays.
1612 base = is the namelist_info of the derived type, when obj is a
1613 component.
1614 base_name = the full name for a derived type, including qualifiers
1615 if any.
1616 The returned value is a pointer to the object beyond the last one
1617 accessed, including nested derived types. Notice that the namelist is
1618 a linear linked list of objects, including derived types and their
1619 components. A tree, of sorts, is implied by the compound names of
1620 the derived type components and this is how this function recurses through
1621 the list. */
1623 /* A generous estimate of the number of characters needed to print
1624 repeat counts and indices, including commas, asterices and brackets. */
1626 #define NML_DIGITS 20
1628 static void
1629 namelist_write_newline (st_parameter_dt *dtp)
1631 if (!is_internal_unit (dtp))
1633 #ifdef HAVE_CRLF
1634 write_character (dtp, "\r\n", 1, 2);
1635 #else
1636 write_character (dtp, "\n", 1, 1);
1637 #endif
1638 return;
1641 if (is_array_io (dtp))
1643 gfc_offset record;
1644 int finished;
1645 char *p;
1646 int length = dtp->u.p.current_unit->bytes_left;
1648 p = write_block (dtp, length);
1649 if (p == NULL)
1650 return;
1652 if (unlikely (is_char4_unit (dtp)))
1654 gfc_char4_t *p4 = (gfc_char4_t *) p;
1655 memset4 (p4, ' ', length);
1657 else
1658 memset (p, ' ', length);
1660 /* Now that the current record has been padded out,
1661 determine where the next record in the array is. */
1662 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
1663 &finished);
1664 if (finished)
1665 dtp->u.p.current_unit->endfile = AT_ENDFILE;
1666 else
1668 /* Now seek to this record */
1669 record = record * dtp->u.p.current_unit->recl;
1671 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
1673 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
1674 return;
1677 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1680 else
1681 write_character (dtp, " ", 1, 1);
1685 static namelist_info *
1686 nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
1687 namelist_info * base, char * base_name)
1689 int rep_ctr;
1690 int num;
1691 int nml_carry;
1692 int len;
1693 index_type obj_size;
1694 index_type nelem;
1695 size_t dim_i;
1696 size_t clen;
1697 index_type elem_ctr;
1698 size_t obj_name_len;
1699 void * p ;
1700 char cup;
1701 char * obj_name;
1702 char * ext_name;
1703 size_t ext_name_len;
1704 char rep_buff[NML_DIGITS];
1705 namelist_info * cmp;
1706 namelist_info * retval = obj->next;
1707 size_t base_name_len;
1708 size_t base_var_name_len;
1709 size_t tot_len;
1710 unit_delim tmp_delim;
1712 /* Set the character to be used to separate values
1713 to a comma or semi-colon. */
1715 char semi_comma =
1716 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1718 /* Write namelist variable names in upper case. If a derived type,
1719 nothing is output. If a component, base and base_name are set. */
1721 if (obj->type != BT_DERIVED)
1723 namelist_write_newline (dtp);
1724 write_character (dtp, " ", 1, 1);
1726 len = 0;
1727 if (base)
1729 len = strlen (base->var_name);
1730 base_name_len = strlen (base_name);
1731 for (dim_i = 0; dim_i < base_name_len; dim_i++)
1733 cup = toupper ((int) base_name[dim_i]);
1734 write_character (dtp, &cup, 1, 1);
1737 clen = strlen (obj->var_name);
1738 for (dim_i = len; dim_i < clen; dim_i++)
1740 cup = toupper ((int) obj->var_name[dim_i]);
1741 write_character (dtp, &cup, 1, 1);
1743 write_character (dtp, "=", 1, 1);
1746 /* Counts the number of data output on a line, including names. */
1748 num = 1;
1750 len = obj->len;
1752 switch (obj->type)
1755 case BT_REAL:
1756 obj_size = size_from_real_kind (len);
1757 break;
1759 case BT_COMPLEX:
1760 obj_size = size_from_complex_kind (len);
1761 break;
1763 case BT_CHARACTER:
1764 obj_size = obj->string_length;
1765 break;
1767 default:
1768 obj_size = len;
1771 if (obj->var_rank)
1772 obj_size = obj->size;
1774 /* Set the index vector and count the number of elements. */
1776 nelem = 1;
1777 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1779 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
1780 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
1783 /* Main loop to output the data held in the object. */
1785 rep_ctr = 1;
1786 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
1789 /* Build the pointer to the data value. The offset is passed by
1790 recursive calls to this function for arrays of derived types.
1791 Is NULL otherwise. */
1793 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
1794 p += offset;
1796 /* Check for repeat counts of intrinsic types. */
1798 if ((elem_ctr < (nelem - 1)) &&
1799 (obj->type != BT_DERIVED) &&
1800 !memcmp (p, (void*)(p + obj_size ), obj_size ))
1802 rep_ctr++;
1805 /* Execute a repeated output. Note the flag no_leading_blank that
1806 is used in the functions used to output the intrinsic types. */
1808 else
1810 if (rep_ctr > 1)
1812 snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
1813 write_character (dtp, rep_buff, 1, strlen (rep_buff));
1814 dtp->u.p.no_leading_blank = 1;
1816 num++;
1818 /* Output the data, if an intrinsic type, or recurse into this
1819 routine to treat derived types. */
1821 switch (obj->type)
1824 case BT_INTEGER:
1825 write_integer (dtp, p, len);
1826 break;
1828 case BT_LOGICAL:
1829 write_logical (dtp, p, len);
1830 break;
1832 case BT_CHARACTER:
1833 tmp_delim = dtp->u.p.current_unit->delim_status;
1834 if (dtp->u.p.nml_delim == '"')
1835 dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
1836 if (dtp->u.p.nml_delim == '\'')
1837 dtp->u.p.current_unit->delim_status = DELIM_APOSTROPHE;
1838 write_character (dtp, p, 1, obj->string_length);
1839 dtp->u.p.current_unit->delim_status = tmp_delim;
1840 break;
1842 case BT_REAL:
1843 write_real (dtp, p, len);
1844 break;
1846 case BT_COMPLEX:
1847 dtp->u.p.no_leading_blank = 0;
1848 num++;
1849 write_complex (dtp, p, len, obj_size);
1850 break;
1852 case BT_DERIVED:
1854 /* To treat a derived type, we need to build two strings:
1855 ext_name = the name, including qualifiers that prepends
1856 component names in the output - passed to
1857 nml_write_obj.
1858 obj_name = the derived type name with no qualifiers but %
1859 appended. This is used to identify the
1860 components. */
1862 /* First ext_name => get length of all possible components */
1864 base_name_len = base_name ? strlen (base_name) : 0;
1865 base_var_name_len = base ? strlen (base->var_name) : 0;
1866 ext_name_len = base_name_len + base_var_name_len
1867 + strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
1868 ext_name = (char*)xmalloc (ext_name_len);
1870 memcpy (ext_name, base_name, base_name_len);
1871 clen = strlen (obj->var_name + base_var_name_len);
1872 memcpy (ext_name + base_name_len,
1873 obj->var_name + base_var_name_len, clen);
1875 /* Append the qualifier. */
1877 tot_len = base_name_len + clen;
1878 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1880 if (!dim_i)
1882 ext_name[tot_len] = '(';
1883 tot_len++;
1885 snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
1886 (int) obj->ls[dim_i].idx);
1887 tot_len += strlen (ext_name + tot_len);
1888 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
1889 tot_len++;
1892 ext_name[tot_len] = '\0';
1894 /* Now obj_name. */
1896 obj_name_len = strlen (obj->var_name) + 1;
1897 obj_name = xmalloc (obj_name_len+1);
1898 memcpy (obj_name, obj->var_name, obj_name_len-1);
1899 memcpy (obj_name + obj_name_len-1, "%", 2);
1901 /* Now loop over the components. Update the component pointer
1902 with the return value from nml_write_obj => this loop jumps
1903 past nested derived types. */
1905 for (cmp = obj->next;
1906 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
1907 cmp = retval)
1909 retval = nml_write_obj (dtp, cmp,
1910 (index_type)(p - obj->mem_pos),
1911 obj, ext_name);
1914 free (obj_name);
1915 free (ext_name);
1916 goto obj_loop;
1918 default:
1919 internal_error (&dtp->common, "Bad type for namelist write");
1922 /* Reset the leading blank suppression, write a comma (or semi-colon)
1923 and, if 5 values have been output, write a newline and advance
1924 to column 2. Reset the repeat counter. */
1926 dtp->u.p.no_leading_blank = 0;
1927 write_character (dtp, &semi_comma, 1, 1);
1928 if (num > 5)
1930 num = 0;
1931 namelist_write_newline (dtp);
1932 write_character (dtp, " ", 1, 1);
1934 rep_ctr = 1;
1937 /* Cycle through and increment the index vector. */
1939 obj_loop:
1941 nml_carry = 1;
1942 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
1944 obj->ls[dim_i].idx += nml_carry ;
1945 nml_carry = 0;
1946 if (obj->ls[dim_i].idx > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
1948 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
1949 nml_carry = 1;
1954 /* Return a pointer beyond the furthest object accessed. */
1956 return retval;
1960 /* This is the entry function for namelist writes. It outputs the name
1961 of the namelist and iterates through the namelist by calls to
1962 nml_write_obj. The call below has dummys in the arguments used in
1963 the treatment of derived types. */
1965 void
1966 namelist_write (st_parameter_dt *dtp)
1968 namelist_info * t1, *t2, *dummy = NULL;
1969 index_type i;
1970 index_type dummy_offset = 0;
1971 char c;
1972 char * dummy_name = NULL;
1973 unit_delim tmp_delim = DELIM_UNSPECIFIED;
1975 /* Set the delimiter for namelist output. */
1976 tmp_delim = dtp->u.p.current_unit->delim_status;
1978 dtp->u.p.nml_delim = tmp_delim == DELIM_APOSTROPHE ? '\'' : '"';
1980 /* Temporarily disable namelist delimters. */
1981 dtp->u.p.current_unit->delim_status = DELIM_NONE;
1983 write_character (dtp, "&", 1, 1);
1985 /* Write namelist name in upper case - f95 std. */
1986 for (i = 0 ;i < dtp->namelist_name_len ;i++ )
1988 c = toupper ((int) dtp->namelist_name[i]);
1989 write_character (dtp, &c, 1 ,1);
1992 if (dtp->u.p.ionml != NULL)
1994 t1 = dtp->u.p.ionml;
1995 while (t1 != NULL)
1997 t2 = t1;
1998 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
2002 namelist_write_newline (dtp);
2003 write_character (dtp, " /", 1, 2);
2004 /* Restore the original delimiter. */
2005 dtp->u.p.current_unit->delim_status = tmp_delim;
2008 #undef NML_DIGITS