Add run tests for recent sibcall patches
[official-gcc.git] / libgfortran / io / write.c
blobc8bba3c0bb8774c57e7544149e9d4d1373a5c2d4
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 /* Check the first character in source if we are using CC_FORTRAN
232 and set the cc.type appropriately. The cc.type is used later by write_cc
233 to determine the output start-of-record, and next_record_cc to determine the
234 output end-of-record.
235 This function is called before the output buffer is allocated, so alloc_len
236 is set to the appropriate size to allocate. */
238 static void
239 write_check_cc (st_parameter_dt *dtp, const char **source, int *alloc_len)
241 /* Only valid for CARRIAGECONTROL=FORTRAN. */
242 if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN
243 || alloc_len == NULL || source == NULL)
244 return;
246 /* Peek at the first character. */
247 int c = (*alloc_len > 0) ? (*source)[0] : EOF;
248 if (c != EOF)
250 /* The start-of-record character which will be printed. */
251 dtp->u.p.cc.u.start = '\n';
252 /* The number of characters to print at the start-of-record.
253 len > 1 means copy the SOR character multiple times.
254 len == 0 means no SOR will be output. */
255 dtp->u.p.cc.len = 1;
257 switch (c)
259 case '+':
260 dtp->u.p.cc.type = CCF_OVERPRINT;
261 dtp->u.p.cc.len = 0;
262 break;
263 case '-':
264 dtp->u.p.cc.type = CCF_ONE_LF;
265 dtp->u.p.cc.len = 1;
266 break;
267 case '0':
268 dtp->u.p.cc.type = CCF_TWO_LF;
269 dtp->u.p.cc.len = 2;
270 break;
271 case '1':
272 dtp->u.p.cc.type = CCF_PAGE_FEED;
273 dtp->u.p.cc.len = 1;
274 dtp->u.p.cc.u.start = '\f';
275 break;
276 case '$':
277 dtp->u.p.cc.type = CCF_PROMPT;
278 dtp->u.p.cc.len = 1;
279 break;
280 case '\0':
281 dtp->u.p.cc.type = CCF_OVERPRINT_NOA;
282 dtp->u.p.cc.len = 0;
283 break;
284 default:
285 /* In the default case we copy ONE_LF. */
286 dtp->u.p.cc.type = CCF_DEFAULT;
287 dtp->u.p.cc.len = 1;
288 break;
291 /* We add n-1 to alloc_len so our write buffer is the right size.
292 We are replacing the first character, and possibly prepending some
293 additional characters. Note for n==0, we actually subtract one from
294 alloc_len, which is correct, since that character is skipped. */
295 if (*alloc_len > 0)
297 *source += 1;
298 *alloc_len += dtp->u.p.cc.len - 1;
300 /* If we have no input, there is no first character to replace. Make
301 sure we still allocate enough space for the start-of-record string. */
302 else
303 *alloc_len = dtp->u.p.cc.len;
308 /* Write the start-of-record character(s) for CC_FORTRAN.
309 Also adjusts the 'cc' struct to contain the end-of-record character
310 for next_record_cc.
311 The source_len is set to the remaining length to copy from the source,
312 after the start-of-record string was inserted. */
314 static char *
315 write_cc (st_parameter_dt *dtp, char *p, int *source_len)
317 /* Only valid for CARRIAGECONTROL=FORTRAN. */
318 if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN || source_len == NULL)
319 return p;
321 /* Write the start-of-record string to the output buffer. Note that len is
322 never more than 2. */
323 if (dtp->u.p.cc.len > 0)
325 *(p++) = dtp->u.p.cc.u.start;
326 if (dtp->u.p.cc.len > 1)
327 *(p++) = dtp->u.p.cc.u.start;
329 /* source_len comes from write_check_cc where it is set to the full
330 allocated length of the output buffer. Therefore we subtract off the
331 length of the SOR string to obtain the remaining source length. */
332 *source_len -= dtp->u.p.cc.len;
335 /* Common case. */
336 dtp->u.p.cc.len = 1;
337 dtp->u.p.cc.u.end = '\r';
339 /* Update end-of-record character for next_record_w. */
340 switch (dtp->u.p.cc.type)
342 case CCF_PROMPT:
343 case CCF_OVERPRINT_NOA:
344 /* No end-of-record. */
345 dtp->u.p.cc.len = 0;
346 dtp->u.p.cc.u.end = '\0';
347 break;
348 case CCF_OVERPRINT:
349 case CCF_ONE_LF:
350 case CCF_TWO_LF:
351 case CCF_PAGE_FEED:
352 case CCF_DEFAULT:
353 default:
354 /* Carriage return. */
355 dtp->u.p.cc.len = 1;
356 dtp->u.p.cc.u.end = '\r';
357 break;
360 return p;
363 void
364 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
366 int wlen;
367 char *p;
369 wlen = f->u.string.length < 0
370 || (f->format == FMT_G && f->u.string.length == 0)
371 ? len : f->u.string.length;
373 #ifdef HAVE_CRLF
374 /* If this is formatted STREAM IO convert any embedded line feed characters
375 to CR_LF on systems that use that sequence for newlines. See F2003
376 Standard sections 10.6.3 and 9.9 for further information. */
377 if (is_stream_io (dtp))
379 const char crlf[] = "\r\n";
380 int i, q, bytes;
381 q = bytes = 0;
383 /* Write out any padding if needed. */
384 if (len < wlen)
386 p = write_block (dtp, wlen - len);
387 if (p == NULL)
388 return;
389 memset (p, ' ', wlen - len);
392 /* Scan the source string looking for '\n' and convert it if found. */
393 for (i = 0; i < wlen; i++)
395 if (source[i] == '\n')
397 /* Write out the previously scanned characters in the string. */
398 if (bytes > 0)
400 p = write_block (dtp, bytes);
401 if (p == NULL)
402 return;
403 memcpy (p, &source[q], bytes);
404 q += bytes;
405 bytes = 0;
408 /* Write out the CR_LF sequence. */
409 q++;
410 p = write_block (dtp, 2);
411 if (p == NULL)
412 return;
413 memcpy (p, crlf, 2);
415 else
416 bytes++;
419 /* Write out any remaining bytes if no LF was found. */
420 if (bytes > 0)
422 p = write_block (dtp, bytes);
423 if (p == NULL)
424 return;
425 memcpy (p, &source[q], bytes);
428 else
430 #endif
431 if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
432 write_check_cc (dtp, &source, &wlen);
434 p = write_block (dtp, wlen);
435 if (p == NULL)
436 return;
438 if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
439 p = write_cc (dtp, p, &wlen);
441 if (unlikely (is_char4_unit (dtp)))
443 gfc_char4_t *p4 = (gfc_char4_t *) p;
444 if (wlen < len)
445 memcpy4 (p4, source, wlen);
446 else
448 memset4 (p4, ' ', wlen - len);
449 memcpy4 (p4 + wlen - len, source, len);
451 return;
454 if (wlen < len)
455 memcpy (p, source, wlen);
456 else
458 memset (p, ' ', wlen - len);
459 memcpy (p + wlen - len, source, len);
461 #ifdef HAVE_CRLF
463 #endif
467 /* The primary difference between write_a_char4 and write_a is that we have to
468 deal with writing from the first byte of the 4-byte character and pay
469 attention to the most significant bytes. For ENCODING="default" write the
470 lowest significant byte. If the 3 most significant bytes contain
471 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
472 to the UTF-8 encoded string before writing out. */
474 void
475 write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
477 int wlen;
478 gfc_char4_t *q;
480 wlen = f->u.string.length < 0
481 || (f->format == FMT_G && f->u.string.length == 0)
482 ? len : f->u.string.length;
484 q = (gfc_char4_t *) source;
485 #ifdef HAVE_CRLF
486 /* If this is formatted STREAM IO convert any embedded line feed characters
487 to CR_LF on systems that use that sequence for newlines. See F2003
488 Standard sections 10.6.3 and 9.9 for further information. */
489 if (is_stream_io (dtp))
491 const gfc_char4_t crlf[] = {0x000d,0x000a};
492 int i, bytes;
493 gfc_char4_t *qq;
494 bytes = 0;
496 /* Write out any padding if needed. */
497 if (len < wlen)
499 char *p;
500 p = write_block (dtp, wlen - len);
501 if (p == NULL)
502 return;
503 memset (p, ' ', wlen - len);
506 /* Scan the source string looking for '\n' and convert it if found. */
507 qq = (gfc_char4_t *) source;
508 for (i = 0; i < wlen; i++)
510 if (qq[i] == '\n')
512 /* Write out the previously scanned characters in the string. */
513 if (bytes > 0)
515 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
516 write_utf8_char4 (dtp, q, bytes, 0);
517 else
518 write_default_char4 (dtp, q, bytes, 0);
519 bytes = 0;
522 /* Write out the CR_LF sequence. */
523 write_default_char4 (dtp, crlf, 2, 0);
525 else
526 bytes++;
529 /* Write out any remaining bytes if no LF was found. */
530 if (bytes > 0)
532 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
533 write_utf8_char4 (dtp, q, bytes, 0);
534 else
535 write_default_char4 (dtp, q, bytes, 0);
538 else
540 #endif
541 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
542 write_utf8_char4 (dtp, q, len, wlen);
543 else
544 write_default_char4 (dtp, q, len, wlen);
545 #ifdef HAVE_CRLF
547 #endif
551 static GFC_INTEGER_LARGEST
552 extract_int (const void *p, int len)
554 GFC_INTEGER_LARGEST i = 0;
556 if (p == NULL)
557 return i;
559 switch (len)
561 case 1:
563 GFC_INTEGER_1 tmp;
564 memcpy ((void *) &tmp, p, len);
565 i = tmp;
567 break;
568 case 2:
570 GFC_INTEGER_2 tmp;
571 memcpy ((void *) &tmp, p, len);
572 i = tmp;
574 break;
575 case 4:
577 GFC_INTEGER_4 tmp;
578 memcpy ((void *) &tmp, p, len);
579 i = tmp;
581 break;
582 case 8:
584 GFC_INTEGER_8 tmp;
585 memcpy ((void *) &tmp, p, len);
586 i = tmp;
588 break;
589 #ifdef HAVE_GFC_INTEGER_16
590 case 16:
592 GFC_INTEGER_16 tmp;
593 memcpy ((void *) &tmp, p, len);
594 i = tmp;
596 break;
597 #endif
598 default:
599 internal_error (NULL, "bad integer kind");
602 return i;
605 static GFC_UINTEGER_LARGEST
606 extract_uint (const void *p, int len)
608 GFC_UINTEGER_LARGEST i = 0;
610 if (p == NULL)
611 return i;
613 switch (len)
615 case 1:
617 GFC_INTEGER_1 tmp;
618 memcpy ((void *) &tmp, p, len);
619 i = (GFC_UINTEGER_1) tmp;
621 break;
622 case 2:
624 GFC_INTEGER_2 tmp;
625 memcpy ((void *) &tmp, p, len);
626 i = (GFC_UINTEGER_2) tmp;
628 break;
629 case 4:
631 GFC_INTEGER_4 tmp;
632 memcpy ((void *) &tmp, p, len);
633 i = (GFC_UINTEGER_4) tmp;
635 break;
636 case 8:
638 GFC_INTEGER_8 tmp;
639 memcpy ((void *) &tmp, p, len);
640 i = (GFC_UINTEGER_8) tmp;
642 break;
643 #ifdef HAVE_GFC_INTEGER_16
644 case 10:
645 case 16:
647 GFC_INTEGER_16 tmp = 0;
648 memcpy ((void *) &tmp, p, len);
649 i = (GFC_UINTEGER_16) tmp;
651 break;
652 #endif
653 default:
654 internal_error (NULL, "bad integer kind");
657 return i;
661 void
662 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
664 char *p;
665 int wlen;
666 GFC_INTEGER_LARGEST n;
668 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
670 p = write_block (dtp, wlen);
671 if (p == NULL)
672 return;
674 n = extract_int (source, len);
676 if (unlikely (is_char4_unit (dtp)))
678 gfc_char4_t *p4 = (gfc_char4_t *) p;
679 memset4 (p4, ' ', wlen -1);
680 p4[wlen - 1] = (n) ? 'T' : 'F';
681 return;
684 memset (p, ' ', wlen -1);
685 p[wlen - 1] = (n) ? 'T' : 'F';
689 static void
690 write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
692 int w, m, digits, nzero, nblank;
693 char *p;
695 w = f->u.integer.w;
696 m = f->u.integer.m;
698 /* Special case: */
700 if (m == 0 && n == 0)
702 if (w == 0)
703 w = 1;
705 p = write_block (dtp, w);
706 if (p == NULL)
707 return;
708 if (unlikely (is_char4_unit (dtp)))
710 gfc_char4_t *p4 = (gfc_char4_t *) p;
711 memset4 (p4, ' ', w);
713 else
714 memset (p, ' ', w);
715 goto done;
718 digits = strlen (q);
720 /* Select a width if none was specified. The idea here is to always
721 print something. */
723 if (w == 0)
724 w = ((digits < m) ? m : digits);
726 p = write_block (dtp, w);
727 if (p == NULL)
728 return;
730 nzero = 0;
731 if (digits < m)
732 nzero = m - digits;
734 /* See if things will work. */
736 nblank = w - (nzero + digits);
738 if (unlikely (is_char4_unit (dtp)))
740 gfc_char4_t *p4 = (gfc_char4_t *) p;
741 if (nblank < 0)
743 memset4 (p4, '*', w);
744 return;
747 if (!dtp->u.p.no_leading_blank)
749 memset4 (p4, ' ', nblank);
750 q += nblank;
751 memset4 (p4, '0', nzero);
752 q += nzero;
753 memcpy4 (p4, q, digits);
755 else
757 memset4 (p4, '0', nzero);
758 q += nzero;
759 memcpy4 (p4, q, digits);
760 q += digits;
761 memset4 (p4, ' ', nblank);
762 dtp->u.p.no_leading_blank = 0;
764 return;
767 if (nblank < 0)
769 star_fill (p, w);
770 goto done;
773 if (!dtp->u.p.no_leading_blank)
775 memset (p, ' ', nblank);
776 p += nblank;
777 memset (p, '0', nzero);
778 p += nzero;
779 memcpy (p, q, digits);
781 else
783 memset (p, '0', nzero);
784 p += nzero;
785 memcpy (p, q, digits);
786 p += digits;
787 memset (p, ' ', nblank);
788 dtp->u.p.no_leading_blank = 0;
791 done:
792 return;
795 static void
796 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
797 int len,
798 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
800 GFC_INTEGER_LARGEST n = 0;
801 int w, m, digits, nsign, nzero, nblank;
802 char *p;
803 const char *q;
804 sign_t sign;
805 char itoa_buf[GFC_BTOA_BUF_SIZE];
807 w = f->u.integer.w;
808 m = f->format == FMT_G ? -1 : f->u.integer.m;
810 n = extract_int (source, len);
812 /* Special case: */
813 if (m == 0 && n == 0)
815 if (w == 0)
816 w = 1;
818 p = write_block (dtp, w);
819 if (p == NULL)
820 return;
821 if (unlikely (is_char4_unit (dtp)))
823 gfc_char4_t *p4 = (gfc_char4_t *) p;
824 memset4 (p4, ' ', w);
826 else
827 memset (p, ' ', w);
828 goto done;
831 sign = calculate_sign (dtp, n < 0);
832 if (n < 0)
833 n = -n;
834 nsign = sign == S_NONE ? 0 : 1;
836 /* conv calls itoa which sets the negative sign needed
837 by write_integer. The sign '+' or '-' is set below based on sign
838 calculated above, so we just point past the sign in the string
839 before proceeding to avoid double signs in corner cases.
840 (see PR38504) */
841 q = conv (n, itoa_buf, sizeof (itoa_buf));
842 if (*q == '-')
843 q++;
845 digits = strlen (q);
847 /* Select a width if none was specified. The idea here is to always
848 print something. */
850 if (w == 0)
851 w = ((digits < m) ? m : digits) + nsign;
853 p = write_block (dtp, w);
854 if (p == NULL)
855 return;
857 nzero = 0;
858 if (digits < m)
859 nzero = m - digits;
861 /* See if things will work. */
863 nblank = w - (nsign + nzero + digits);
865 if (unlikely (is_char4_unit (dtp)))
867 gfc_char4_t * p4 = (gfc_char4_t *) p;
868 if (nblank < 0)
870 memset4 (p4, '*', w);
871 goto done;
874 memset4 (p4, ' ', nblank);
875 p4 += nblank;
877 switch (sign)
879 case S_PLUS:
880 *p4++ = '+';
881 break;
882 case S_MINUS:
883 *p4++ = '-';
884 break;
885 case S_NONE:
886 break;
889 memset4 (p4, '0', nzero);
890 p4 += nzero;
892 memcpy4 (p4, q, digits);
893 return;
896 if (nblank < 0)
898 star_fill (p, w);
899 goto done;
902 memset (p, ' ', nblank);
903 p += nblank;
905 switch (sign)
907 case S_PLUS:
908 *p++ = '+';
909 break;
910 case S_MINUS:
911 *p++ = '-';
912 break;
913 case S_NONE:
914 break;
917 memset (p, '0', nzero);
918 p += nzero;
920 memcpy (p, q, digits);
922 done:
923 return;
927 /* Convert unsigned octal to ascii. */
929 static const char *
930 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
932 char *p;
934 assert (len >= GFC_OTOA_BUF_SIZE);
936 if (n == 0)
937 return "0";
939 p = buffer + GFC_OTOA_BUF_SIZE - 1;
940 *p = '\0';
942 while (n != 0)
944 *--p = '0' + (n & 7);
945 n >>= 3;
948 return p;
952 /* Convert unsigned binary to ascii. */
954 static const char *
955 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
957 char *p;
959 assert (len >= GFC_BTOA_BUF_SIZE);
961 if (n == 0)
962 return "0";
964 p = buffer + GFC_BTOA_BUF_SIZE - 1;
965 *p = '\0';
967 while (n != 0)
969 *--p = '0' + (n & 1);
970 n >>= 1;
973 return p;
976 /* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
977 to convert large reals with kind sizes that exceed the largest integer type
978 available on certain platforms. In these cases, byte by byte conversion is
979 performed. Endianess is taken into account. */
981 /* Conversion to binary. */
983 static const char *
984 btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
986 char *q;
987 int i, j;
989 q = buffer;
990 if (big_endian)
992 const char *p = s;
993 for (i = 0; i < len; i++)
995 char c = *p;
997 /* Test for zero. Needed by write_boz later. */
998 if (*p != 0)
999 *n = 1;
1001 for (j = 0; j < 8; j++)
1003 *q++ = (c & 128) ? '1' : '0';
1004 c <<= 1;
1006 p++;
1009 else
1011 const char *p = s + len - 1;
1012 for (i = 0; i < len; i++)
1014 char c = *p;
1016 /* Test for zero. Needed by write_boz later. */
1017 if (*p != 0)
1018 *n = 1;
1020 for (j = 0; j < 8; j++)
1022 *q++ = (c & 128) ? '1' : '0';
1023 c <<= 1;
1025 p--;
1029 *q = '\0';
1031 if (*n == 0)
1032 return "0";
1034 /* Move past any leading zeros. */
1035 while (*buffer == '0')
1036 buffer++;
1038 return buffer;
1042 /* Conversion to octal. */
1044 static const char *
1045 otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
1047 char *q;
1048 int i, j, k;
1049 uint8_t octet;
1051 q = buffer + GFC_OTOA_BUF_SIZE - 1;
1052 *q = '\0';
1053 i = k = octet = 0;
1055 if (big_endian)
1057 const char *p = s + len - 1;
1058 char c = *p;
1059 while (i < len)
1061 /* Test for zero. Needed by write_boz later. */
1062 if (*p != 0)
1063 *n = 1;
1065 for (j = 0; j < 3 && i < len; j++)
1067 octet |= (c & 1) << j;
1068 c >>= 1;
1069 if (++k > 7)
1071 i++;
1072 k = 0;
1073 c = *--p;
1076 *--q = '0' + octet;
1077 octet = 0;
1080 else
1082 const char *p = s;
1083 char c = *p;
1084 while (i < len)
1086 /* Test for zero. Needed by write_boz later. */
1087 if (*p != 0)
1088 *n = 1;
1090 for (j = 0; j < 3 && i < len; j++)
1092 octet |= (c & 1) << j;
1093 c >>= 1;
1094 if (++k > 7)
1096 i++;
1097 k = 0;
1098 c = *++p;
1101 *--q = '0' + octet;
1102 octet = 0;
1106 if (*n == 0)
1107 return "0";
1109 /* Move past any leading zeros. */
1110 while (*q == '0')
1111 q++;
1113 return q;
1116 /* Conversion to hexidecimal. */
1118 static const char *
1119 ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
1121 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
1122 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
1124 char *q;
1125 uint8_t h, l;
1126 int i;
1128 q = buffer;
1130 if (big_endian)
1132 const char *p = s;
1133 for (i = 0; i < len; i++)
1135 /* Test for zero. Needed by write_boz later. */
1136 if (*p != 0)
1137 *n = 1;
1139 h = (*p >> 4) & 0x0F;
1140 l = *p++ & 0x0F;
1141 *q++ = a[h];
1142 *q++ = a[l];
1145 else
1147 const char *p = s + len - 1;
1148 for (i = 0; i < len; i++)
1150 /* Test for zero. Needed by write_boz later. */
1151 if (*p != 0)
1152 *n = 1;
1154 h = (*p >> 4) & 0x0F;
1155 l = *p-- & 0x0F;
1156 *q++ = a[h];
1157 *q++ = a[l];
1161 *q = '\0';
1163 if (*n == 0)
1164 return "0";
1166 /* Move past any leading zeros. */
1167 while (*buffer == '0')
1168 buffer++;
1170 return buffer;
1174 void
1175 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1177 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
1181 void
1182 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1184 const char *p;
1185 char itoa_buf[GFC_BTOA_BUF_SIZE];
1186 GFC_UINTEGER_LARGEST n = 0;
1188 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1190 p = btoa_big (source, itoa_buf, len, &n);
1191 write_boz (dtp, f, p, n);
1193 else
1195 n = extract_uint (source, len);
1196 p = btoa (n, itoa_buf, sizeof (itoa_buf));
1197 write_boz (dtp, f, p, n);
1202 void
1203 write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1205 const char *p;
1206 char itoa_buf[GFC_OTOA_BUF_SIZE];
1207 GFC_UINTEGER_LARGEST n = 0;
1209 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1211 p = otoa_big (source, itoa_buf, len, &n);
1212 write_boz (dtp, f, p, n);
1214 else
1216 n = extract_uint (source, len);
1217 p = otoa (n, itoa_buf, sizeof (itoa_buf));
1218 write_boz (dtp, f, p, n);
1222 void
1223 write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1225 const char *p;
1226 char itoa_buf[GFC_XTOA_BUF_SIZE];
1227 GFC_UINTEGER_LARGEST n = 0;
1229 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1231 p = ztoa_big (source, itoa_buf, len, &n);
1232 write_boz (dtp, f, p, n);
1234 else
1236 n = extract_uint (source, len);
1237 p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
1238 write_boz (dtp, f, p, n);
1242 /* Take care of the X/TR descriptor. */
1244 void
1245 write_x (st_parameter_dt *dtp, int len, int nspaces)
1247 char *p;
1249 p = write_block (dtp, len);
1250 if (p == NULL)
1251 return;
1252 if (nspaces > 0 && len - nspaces >= 0)
1254 if (unlikely (is_char4_unit (dtp)))
1256 gfc_char4_t *p4 = (gfc_char4_t *) p;
1257 memset4 (&p4[len - nspaces], ' ', nspaces);
1259 else
1260 memset (&p[len - nspaces], ' ', nspaces);
1265 /* List-directed writing. */
1268 /* Write a single character to the output. Returns nonzero if
1269 something goes wrong. */
1271 static int
1272 write_char (st_parameter_dt *dtp, int c)
1274 char *p;
1276 p = write_block (dtp, 1);
1277 if (p == NULL)
1278 return 1;
1279 if (unlikely (is_char4_unit (dtp)))
1281 gfc_char4_t *p4 = (gfc_char4_t *) p;
1282 *p4 = c;
1283 return 0;
1286 *p = (uchar) c;
1288 return 0;
1292 /* Write a list-directed logical value. */
1294 static void
1295 write_logical (st_parameter_dt *dtp, const char *source, int length)
1297 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
1301 /* Write a list-directed integer value. */
1303 static void
1304 write_integer (st_parameter_dt *dtp, const char *source, int length)
1306 char *p;
1307 const char *q;
1308 int digits;
1309 int width;
1310 char itoa_buf[GFC_ITOA_BUF_SIZE];
1312 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1314 switch (length)
1316 case 1:
1317 width = 4;
1318 break;
1320 case 2:
1321 width = 6;
1322 break;
1324 case 4:
1325 width = 11;
1326 break;
1328 case 8:
1329 width = 20;
1330 break;
1332 default:
1333 width = 0;
1334 break;
1337 digits = strlen (q);
1339 if (width < digits)
1340 width = digits;
1341 p = write_block (dtp, width);
1342 if (p == NULL)
1343 return;
1345 if (unlikely (is_char4_unit (dtp)))
1347 gfc_char4_t *p4 = (gfc_char4_t *) p;
1348 if (dtp->u.p.no_leading_blank)
1350 memcpy4 (p4, q, digits);
1351 memset4 (p4 + digits, ' ', width - digits);
1353 else
1355 memset4 (p4, ' ', width - digits);
1356 memcpy4 (p4 + width - digits, q, digits);
1358 return;
1361 if (dtp->u.p.no_leading_blank)
1363 memcpy (p, q, digits);
1364 memset (p + digits, ' ', width - digits);
1366 else
1368 memset (p, ' ', width - digits);
1369 memcpy (p + width - digits, q, digits);
1374 /* Write a list-directed string. We have to worry about delimiting
1375 the strings if the file has been opened in that mode. */
1377 #define DELIM 1
1378 #define NODELIM 0
1380 static void
1381 write_character (st_parameter_dt *dtp, const char *source, int kind, int length, int mode)
1383 int i, extra;
1384 char *p, d;
1386 if (mode == DELIM)
1388 switch (dtp->u.p.current_unit->delim_status)
1390 case DELIM_APOSTROPHE:
1391 d = '\'';
1392 break;
1393 case DELIM_QUOTE:
1394 d = '"';
1395 break;
1396 default:
1397 d = ' ';
1398 break;
1401 else
1402 d = ' ';
1404 if (kind == 1)
1406 if (d == ' ')
1407 extra = 0;
1408 else
1410 extra = 2;
1412 for (i = 0; i < length; i++)
1413 if (source[i] == d)
1414 extra++;
1417 p = write_block (dtp, length + extra);
1418 if (p == NULL)
1419 return;
1421 if (unlikely (is_char4_unit (dtp)))
1423 gfc_char4_t d4 = (gfc_char4_t) d;
1424 gfc_char4_t *p4 = (gfc_char4_t *) p;
1426 if (d4 == ' ')
1427 memcpy4 (p4, source, length);
1428 else
1430 *p4++ = d4;
1432 for (i = 0; i < length; i++)
1434 *p4++ = (gfc_char4_t) source[i];
1435 if (source[i] == d)
1436 *p4++ = d4;
1439 *p4 = d4;
1441 return;
1444 if (d == ' ')
1445 memcpy (p, source, length);
1446 else
1448 *p++ = d;
1450 for (i = 0; i < length; i++)
1452 *p++ = source[i];
1453 if (source[i] == d)
1454 *p++ = d;
1457 *p = d;
1460 else
1462 if (d == ' ')
1464 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1465 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1466 else
1467 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1469 else
1471 p = write_block (dtp, 1);
1472 *p = d;
1474 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1475 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1476 else
1477 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1479 p = write_block (dtp, 1);
1480 *p = d;
1485 /* Floating point helper functions. */
1487 #define BUF_STACK_SZ 256
1489 static int
1490 get_precision (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1492 if (f->format != FMT_EN)
1493 return determine_precision (dtp, f, kind);
1494 else
1495 return determine_en_precision (dtp, f, source, kind);
1498 /* 4932 is the maximum exponent of long double and quad precision, 3
1499 extra characters for the sign, the decimal point, and the
1500 trailing null. Extra digits are added by the calling functions for
1501 requested precision. Likewise for float and double. F0 editing produces
1502 full precision output. */
1503 static int
1504 size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
1506 int size;
1508 if (f->format == FMT_F && f->u.real.w == 0)
1510 switch (kind)
1512 case 4:
1513 size = 38 + 3; /* These constants shown for clarity. */
1514 break;
1515 case 8:
1516 size = 308 + 3;
1517 break;
1518 case 10:
1519 size = 4932 + 3;
1520 break;
1521 case 16:
1522 size = 4932 + 3;
1523 break;
1524 default:
1525 internal_error (&dtp->common, "bad real kind");
1526 break;
1529 else
1530 size = f->u.real.w + 1; /* One byte for a NULL character. */
1532 return size;
1535 static char *
1536 select_buffer (st_parameter_dt *dtp, const fnode *f, int precision,
1537 char *buf, size_t *size, int kind)
1539 char *result;
1541 /* The buffer needs at least one more byte to allow room for normalizing. */
1542 *size = size_from_kind (dtp, f, kind) + precision + 1;
1544 if (*size > BUF_STACK_SZ)
1545 result = xmalloc (*size);
1546 else
1547 result = buf;
1548 return result;
1551 static char *
1552 select_string (st_parameter_dt *dtp, const fnode *f, char *buf, size_t *size,
1553 int kind)
1555 char *result;
1556 *size = size_from_kind (dtp, f, kind) + f->u.real.d;
1557 if (*size > BUF_STACK_SZ)
1558 result = xmalloc (*size);
1559 else
1560 result = buf;
1561 return result;
1564 static void
1565 write_float_string (st_parameter_dt *dtp, char *fstr, size_t len)
1567 char *p = write_block (dtp, len);
1568 if (p == NULL)
1569 return;
1571 if (unlikely (is_char4_unit (dtp)))
1573 gfc_char4_t *p4 = (gfc_char4_t *) p;
1574 memcpy4 (p4, fstr, len);
1575 return;
1577 memcpy (p, fstr, len);
1581 static void
1582 write_float_0 (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1584 char buf_stack[BUF_STACK_SZ];
1585 char str_buf[BUF_STACK_SZ];
1586 char *buffer, *result;
1587 size_t buf_size, res_len;
1589 /* Precision for snprintf call. */
1590 int precision = get_precision (dtp, f, source, kind);
1592 /* String buffer to hold final result. */
1593 result = select_string (dtp, f, str_buf, &res_len, kind);
1595 buffer = select_buffer (dtp, f, precision, buf_stack, &buf_size, kind);
1597 get_float_string (dtp, f, source , kind, 0, buffer,
1598 precision, buf_size, result, &res_len);
1599 write_float_string (dtp, result, res_len);
1601 if (buf_size > BUF_STACK_SZ)
1602 free (buffer);
1603 if (res_len > BUF_STACK_SZ)
1604 free (result);
1607 void
1608 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1610 write_float_0 (dtp, f, p, len);
1614 void
1615 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1617 write_float_0 (dtp, f, p, len);
1621 void
1622 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1624 write_float_0 (dtp, f, p, len);
1628 void
1629 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1631 write_float_0 (dtp, f, p, len);
1635 void
1636 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1638 write_float_0 (dtp, f, p, len);
1642 /* Set an fnode to default format. */
1644 static void
1645 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
1647 f->format = FMT_G;
1648 switch (length)
1650 case 4:
1651 f->u.real.w = 16;
1652 f->u.real.d = 9;
1653 f->u.real.e = 2;
1654 break;
1655 case 8:
1656 f->u.real.w = 25;
1657 f->u.real.d = 17;
1658 f->u.real.e = 3;
1659 break;
1660 case 10:
1661 f->u.real.w = 30;
1662 f->u.real.d = 21;
1663 f->u.real.e = 4;
1664 break;
1665 case 16:
1666 /* Adjust decimal precision depending on binary precision, 106 or 113. */
1667 #if GFC_REAL_16_DIGITS == 113
1668 f->u.real.w = 45;
1669 f->u.real.d = 36;
1670 f->u.real.e = 4;
1671 #else
1672 f->u.real.w = 41;
1673 f->u.real.d = 32;
1674 f->u.real.e = 4;
1675 #endif
1676 break;
1677 default:
1678 internal_error (&dtp->common, "bad real kind");
1679 break;
1683 /* Output a real number with default format.
1684 To guarantee that a binary -> decimal -> binary roundtrip conversion
1685 recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
1686 significant digits for REAL kinds 4, 8, 10, and 16, respectively.
1687 Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
1688 for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
1689 Fortran standard requires outputting an extra digit when the scale
1690 factor is 1 and when the magnitude of the value is such that E
1691 editing is used. However, gfortran compensates for this, and thus
1692 for list formatted the same number of significant digits is
1693 generated both when using F and E editing. */
1695 void
1696 write_real (st_parameter_dt *dtp, const char *source, int kind)
1698 fnode f ;
1699 char buf_stack[BUF_STACK_SZ];
1700 char str_buf[BUF_STACK_SZ];
1701 char *buffer, *result;
1702 size_t buf_size, res_len;
1703 int orig_scale = dtp->u.p.scale_factor;
1704 dtp->u.p.scale_factor = 1;
1705 set_fnode_default (dtp, &f, kind);
1707 /* Precision for snprintf call. */
1708 int precision = get_precision (dtp, &f, source, kind);
1710 /* String buffer to hold final result. */
1711 result = select_string (dtp, &f, str_buf, &res_len, kind);
1713 /* Scratch buffer to hold final result. */
1714 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
1716 get_float_string (dtp, &f, source , kind, 1, buffer,
1717 precision, buf_size, result, &res_len);
1718 write_float_string (dtp, result, res_len);
1720 dtp->u.p.scale_factor = orig_scale;
1721 if (buf_size > BUF_STACK_SZ)
1722 free (buffer);
1723 if (res_len > BUF_STACK_SZ)
1724 free (result);
1727 /* Similar to list formatted REAL output, for kPG0 where k > 0 we
1728 compensate for the extra digit. */
1730 void
1731 write_real_g0 (st_parameter_dt *dtp, const char *source, int kind, int d)
1733 fnode f;
1734 char buf_stack[BUF_STACK_SZ];
1735 char str_buf[BUF_STACK_SZ];
1736 char *buffer, *result;
1737 size_t buf_size, res_len;
1738 int comp_d;
1739 set_fnode_default (dtp, &f, kind);
1741 if (d > 0)
1742 f.u.real.d = d;
1744 /* Compensate for extra digits when using scale factor, d is not
1745 specified, and the magnitude is such that E editing is used. */
1746 if (dtp->u.p.scale_factor > 0 && d == 0)
1747 comp_d = 1;
1748 else
1749 comp_d = 0;
1750 dtp->u.p.g0_no_blanks = 1;
1752 /* Precision for snprintf call. */
1753 int precision = get_precision (dtp, &f, source, kind);
1755 /* String buffer to hold final result. */
1756 result = select_string (dtp, &f, str_buf, &res_len, kind);
1758 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
1760 get_float_string (dtp, &f, source , kind, comp_d, buffer,
1761 precision, buf_size, result, &res_len);
1762 write_float_string (dtp, result, res_len);
1764 dtp->u.p.g0_no_blanks = 0;
1765 if (buf_size > BUF_STACK_SZ)
1766 free (buffer);
1767 if (res_len > BUF_STACK_SZ)
1768 free (result);
1772 static void
1773 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1775 char semi_comma =
1776 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1778 /* Set for no blanks so we get a string result with no leading
1779 blanks. We will pad left later. */
1780 dtp->u.p.g0_no_blanks = 1;
1782 fnode f ;
1783 char buf_stack[BUF_STACK_SZ];
1784 char str1_buf[BUF_STACK_SZ];
1785 char str2_buf[BUF_STACK_SZ];
1786 char *buffer, *result1, *result2;
1787 size_t buf_size, res_len1, res_len2;
1788 int width, lblanks, orig_scale = dtp->u.p.scale_factor;
1790 dtp->u.p.scale_factor = 1;
1791 set_fnode_default (dtp, &f, kind);
1793 /* Set width for two values, parenthesis, and comma. */
1794 width = 2 * f.u.real.w + 3;
1796 /* Set for no blanks so we get a string result with no leading
1797 blanks. We will pad left later. */
1798 dtp->u.p.g0_no_blanks = 1;
1800 /* Precision for snprintf call. */
1801 int precision = get_precision (dtp, &f, source, kind);
1803 /* String buffers to hold final result. */
1804 result1 = select_string (dtp, &f, str1_buf, &res_len1, kind);
1805 result2 = select_string (dtp, &f, str2_buf, &res_len2, kind);
1807 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
1809 get_float_string (dtp, &f, source , kind, 0, buffer,
1810 precision, buf_size, result1, &res_len1);
1811 get_float_string (dtp, &f, source + size / 2 , kind, 0, buffer,
1812 precision, buf_size, result2, &res_len2);
1813 lblanks = width - res_len1 - res_len2 - 3;
1815 write_x (dtp, lblanks, lblanks);
1816 write_char (dtp, '(');
1817 write_float_string (dtp, result1, res_len1);
1818 write_char (dtp, semi_comma);
1819 write_float_string (dtp, result2, res_len2);
1820 write_char (dtp, ')');
1822 dtp->u.p.scale_factor = orig_scale;
1823 dtp->u.p.g0_no_blanks = 0;
1824 if (buf_size > BUF_STACK_SZ)
1825 free (buffer);
1826 if (res_len1 > BUF_STACK_SZ)
1827 free (result1);
1828 if (res_len2 > BUF_STACK_SZ)
1829 free (result2);
1833 /* Write the separator between items. */
1835 static void
1836 write_separator (st_parameter_dt *dtp)
1838 char *p;
1840 p = write_block (dtp, options.separator_len);
1841 if (p == NULL)
1842 return;
1843 if (unlikely (is_char4_unit (dtp)))
1845 gfc_char4_t *p4 = (gfc_char4_t *) p;
1846 memcpy4 (p4, options.separator, options.separator_len);
1848 else
1849 memcpy (p, options.separator, options.separator_len);
1853 /* Write an item with list formatting.
1854 TODO: handle skipping to the next record correctly, particularly
1855 with strings. */
1857 static void
1858 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1859 size_t size)
1861 if (dtp->u.p.current_unit == NULL)
1862 return;
1864 if (dtp->u.p.first_item)
1866 dtp->u.p.first_item = 0;
1867 if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
1868 write_char (dtp, ' ');
1870 else
1872 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1873 (dtp->u.p.current_unit->delim_status != DELIM_NONE
1874 && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
1875 write_separator (dtp);
1878 switch (type)
1880 case BT_INTEGER:
1881 write_integer (dtp, p, kind);
1882 break;
1883 case BT_LOGICAL:
1884 write_logical (dtp, p, kind);
1885 break;
1886 case BT_CHARACTER:
1887 write_character (dtp, p, kind, size, DELIM);
1888 break;
1889 case BT_REAL:
1890 write_real (dtp, p, kind);
1891 break;
1892 case BT_COMPLEX:
1893 write_complex (dtp, p, kind, size);
1894 break;
1895 case BT_CLASS:
1897 int unit = dtp->u.p.current_unit->unit_number;
1898 char iotype[] = "LISTDIRECTED";
1899 gfc_charlen_type iotype_len = 12;
1900 char tmp_iomsg[IOMSG_LEN] = "";
1901 char *child_iomsg;
1902 gfc_charlen_type child_iomsg_len;
1903 int noiostat;
1904 int *child_iostat = NULL;
1905 gfc_array_i4 vlist;
1907 GFC_DESCRIPTOR_DATA(&vlist) = NULL;
1908 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
1910 /* Set iostat, intent(out). */
1911 noiostat = 0;
1912 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1913 dtp->common.iostat : &noiostat;
1915 /* Set iomsge, intent(inout). */
1916 if (dtp->common.flags & IOPARM_HAS_IOMSG)
1918 child_iomsg = dtp->common.iomsg;
1919 child_iomsg_len = dtp->common.iomsg_len;
1921 else
1923 child_iomsg = tmp_iomsg;
1924 child_iomsg_len = IOMSG_LEN;
1927 /* Call the user defined formatted WRITE procedure. */
1928 dtp->u.p.current_unit->child_dtio++;
1929 dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
1930 child_iostat, child_iomsg,
1931 iotype_len, child_iomsg_len);
1932 dtp->u.p.current_unit->child_dtio--;
1934 break;
1935 default:
1936 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1939 fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
1940 dtp->u.p.char_flag = (type == BT_CHARACTER);
1944 void
1945 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1946 size_t size, size_t nelems)
1948 size_t elem;
1949 char *tmp;
1950 size_t stride = type == BT_CHARACTER ?
1951 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1953 tmp = (char *) p;
1955 /* Big loop over all the elements. */
1956 for (elem = 0; elem < nelems; elem++)
1958 dtp->u.p.item_count++;
1959 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
1963 /* NAMELIST OUTPUT
1965 nml_write_obj writes a namelist object to the output stream. It is called
1966 recursively for derived type components:
1967 obj = is the namelist_info for the current object.
1968 offset = the offset relative to the address held by the object for
1969 derived type arrays.
1970 base = is the namelist_info of the derived type, when obj is a
1971 component.
1972 base_name = the full name for a derived type, including qualifiers
1973 if any.
1974 The returned value is a pointer to the object beyond the last one
1975 accessed, including nested derived types. Notice that the namelist is
1976 a linear linked list of objects, including derived types and their
1977 components. A tree, of sorts, is implied by the compound names of
1978 the derived type components and this is how this function recurses through
1979 the list. */
1981 /* A generous estimate of the number of characters needed to print
1982 repeat counts and indices, including commas, asterices and brackets. */
1984 #define NML_DIGITS 20
1986 static void
1987 namelist_write_newline (st_parameter_dt *dtp)
1989 if (!is_internal_unit (dtp))
1991 #ifdef HAVE_CRLF
1992 write_character (dtp, "\r\n", 1, 2, NODELIM);
1993 #else
1994 write_character (dtp, "\n", 1, 1, NODELIM);
1995 #endif
1996 return;
1999 if (is_array_io (dtp))
2001 gfc_offset record;
2002 int finished;
2003 char *p;
2004 int length = dtp->u.p.current_unit->bytes_left;
2006 p = write_block (dtp, length);
2007 if (p == NULL)
2008 return;
2010 if (unlikely (is_char4_unit (dtp)))
2012 gfc_char4_t *p4 = (gfc_char4_t *) p;
2013 memset4 (p4, ' ', length);
2015 else
2016 memset (p, ' ', length);
2018 /* Now that the current record has been padded out,
2019 determine where the next record in the array is. */
2020 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
2021 &finished);
2022 if (finished)
2023 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2024 else
2026 /* Now seek to this record */
2027 record = record * dtp->u.p.current_unit->recl;
2029 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
2031 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
2032 return;
2035 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2038 else
2039 write_character (dtp, " ", 1, 1, NODELIM);
2043 static namelist_info *
2044 nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
2045 namelist_info * base, char * base_name)
2047 int rep_ctr;
2048 int num;
2049 int nml_carry;
2050 int len;
2051 index_type obj_size;
2052 index_type nelem;
2053 size_t dim_i;
2054 size_t clen;
2055 index_type elem_ctr;
2056 size_t obj_name_len;
2057 void * p;
2058 char cup;
2059 char * obj_name;
2060 char * ext_name;
2061 char * q;
2062 size_t ext_name_len;
2063 char rep_buff[NML_DIGITS];
2064 namelist_info * cmp;
2065 namelist_info * retval = obj->next;
2066 size_t base_name_len;
2067 size_t base_var_name_len;
2068 size_t tot_len;
2070 /* Set the character to be used to separate values
2071 to a comma or semi-colon. */
2073 char semi_comma =
2074 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
2076 /* Write namelist variable names in upper case. If a derived type,
2077 nothing is output. If a component, base and base_name are set. */
2079 if (obj->type != BT_DERIVED)
2081 namelist_write_newline (dtp);
2082 write_character (dtp, " ", 1, 1, NODELIM);
2084 len = 0;
2085 if (base)
2087 len = strlen (base->var_name);
2088 base_name_len = strlen (base_name);
2089 for (dim_i = 0; dim_i < base_name_len; dim_i++)
2091 cup = toupper ((int) base_name[dim_i]);
2092 write_character (dtp, &cup, 1, 1, NODELIM);
2095 clen = strlen (obj->var_name);
2096 for (dim_i = len; dim_i < clen; dim_i++)
2098 cup = toupper ((int) obj->var_name[dim_i]);
2099 if (cup == '+')
2100 cup = '%';
2101 write_character (dtp, &cup, 1, 1, NODELIM);
2103 write_character (dtp, "=", 1, 1, NODELIM);
2106 /* Counts the number of data output on a line, including names. */
2108 num = 1;
2110 len = obj->len;
2112 switch (obj->type)
2115 case BT_REAL:
2116 obj_size = size_from_real_kind (len);
2117 break;
2119 case BT_COMPLEX:
2120 obj_size = size_from_complex_kind (len);
2121 break;
2123 case BT_CHARACTER:
2124 obj_size = obj->string_length;
2125 break;
2127 default:
2128 obj_size = len;
2131 if (obj->var_rank)
2132 obj_size = obj->size;
2134 /* Set the index vector and count the number of elements. */
2136 nelem = 1;
2137 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
2139 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
2140 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
2143 /* Main loop to output the data held in the object. */
2145 rep_ctr = 1;
2146 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
2149 /* Build the pointer to the data value. The offset is passed by
2150 recursive calls to this function for arrays of derived types.
2151 Is NULL otherwise. */
2153 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
2154 p += offset;
2156 /* Check for repeat counts of intrinsic types. */
2158 if ((elem_ctr < (nelem - 1)) &&
2159 (obj->type != BT_DERIVED) &&
2160 !memcmp (p, (void*)(p + obj_size ), obj_size ))
2162 rep_ctr++;
2165 /* Execute a repeated output. Note the flag no_leading_blank that
2166 is used in the functions used to output the intrinsic types. */
2168 else
2170 if (rep_ctr > 1)
2172 snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
2173 write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
2174 dtp->u.p.no_leading_blank = 1;
2176 num++;
2178 /* Output the data, if an intrinsic type, or recurse into this
2179 routine to treat derived types. */
2181 switch (obj->type)
2184 case BT_INTEGER:
2185 write_integer (dtp, p, len);
2186 break;
2188 case BT_LOGICAL:
2189 write_logical (dtp, p, len);
2190 break;
2192 case BT_CHARACTER:
2193 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
2194 write_character (dtp, p, 4, obj->string_length, DELIM);
2195 else
2196 write_character (dtp, p, 1, obj->string_length, DELIM);
2197 break;
2199 case BT_REAL:
2200 write_real (dtp, p, len);
2201 break;
2203 case BT_COMPLEX:
2204 dtp->u.p.no_leading_blank = 0;
2205 num++;
2206 write_complex (dtp, p, len, obj_size);
2207 break;
2209 case BT_DERIVED:
2210 case BT_CLASS:
2211 /* To treat a derived type, we need to build two strings:
2212 ext_name = the name, including qualifiers that prepends
2213 component names in the output - passed to
2214 nml_write_obj.
2215 obj_name = the derived type name with no qualifiers but %
2216 appended. This is used to identify the
2217 components. */
2219 /* First ext_name => get length of all possible components */
2220 if (obj->dtio_sub != NULL)
2222 int unit = dtp->u.p.current_unit->unit_number;
2223 char iotype[] = "NAMELIST";
2224 gfc_charlen_type iotype_len = 8;
2225 char tmp_iomsg[IOMSG_LEN] = "";
2226 char *child_iomsg;
2227 gfc_charlen_type child_iomsg_len;
2228 int noiostat;
2229 int *child_iostat = NULL;
2230 gfc_array_i4 vlist;
2231 gfc_class list_obj;
2232 formatted_dtio dtio_ptr = (formatted_dtio)obj->dtio_sub;
2234 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
2236 list_obj.data = p;
2237 list_obj.vptr = obj->vtable;
2238 list_obj.len = 0;
2240 /* Set iostat, intent(out). */
2241 noiostat = 0;
2242 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
2243 dtp->common.iostat : &noiostat;
2245 /* Set iomsg, intent(inout). */
2246 if (dtp->common.flags & IOPARM_HAS_IOMSG)
2248 child_iomsg = dtp->common.iomsg;
2249 child_iomsg_len = dtp->common.iomsg_len;
2251 else
2253 child_iomsg = tmp_iomsg;
2254 child_iomsg_len = IOMSG_LEN;
2256 namelist_write_newline (dtp);
2257 /* Call the user defined formatted WRITE procedure. */
2258 dtp->u.p.current_unit->child_dtio++;
2259 dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
2260 child_iostat, child_iomsg,
2261 iotype_len, child_iomsg_len);
2262 dtp->u.p.current_unit->child_dtio--;
2264 goto obj_loop;
2267 base_name_len = base_name ? strlen (base_name) : 0;
2268 base_var_name_len = base ? strlen (base->var_name) : 0;
2269 ext_name_len = base_name_len + base_var_name_len
2270 + strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
2271 ext_name = xmalloc (ext_name_len);
2273 if (base_name)
2274 memcpy (ext_name, base_name, base_name_len);
2275 clen = strlen (obj->var_name + base_var_name_len);
2276 memcpy (ext_name + base_name_len,
2277 obj->var_name + base_var_name_len, clen);
2279 /* Append the qualifier. */
2281 tot_len = base_name_len + clen;
2282 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
2284 if (!dim_i)
2286 ext_name[tot_len] = '(';
2287 tot_len++;
2289 snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
2290 (int) obj->ls[dim_i].idx);
2291 tot_len += strlen (ext_name + tot_len);
2292 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
2293 tot_len++;
2296 ext_name[tot_len] = '\0';
2297 for (q = ext_name; *q; q++)
2298 if (*q == '+')
2299 *q = '%';
2301 /* Now obj_name. */
2303 obj_name_len = strlen (obj->var_name) + 1;
2304 obj_name = xmalloc (obj_name_len + 1);
2305 memcpy (obj_name, obj->var_name, obj_name_len-1);
2306 memcpy (obj_name + obj_name_len-1, "%", 2);
2308 /* Now loop over the components. Update the component pointer
2309 with the return value from nml_write_obj => this loop jumps
2310 past nested derived types. */
2312 for (cmp = obj->next;
2313 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
2314 cmp = retval)
2316 retval = nml_write_obj (dtp, cmp,
2317 (index_type)(p - obj->mem_pos),
2318 obj, ext_name);
2321 free (obj_name);
2322 free (ext_name);
2323 goto obj_loop;
2325 default:
2326 internal_error (&dtp->common, "Bad type for namelist write");
2329 /* Reset the leading blank suppression, write a comma (or semi-colon)
2330 and, if 5 values have been output, write a newline and advance
2331 to column 2. Reset the repeat counter. */
2333 dtp->u.p.no_leading_blank = 0;
2334 if (obj->type == BT_CHARACTER)
2336 if (dtp->u.p.nml_delim != '\0')
2337 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2339 else
2340 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2341 if (num > 5)
2343 num = 0;
2344 if (dtp->u.p.nml_delim == '\0')
2345 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2346 namelist_write_newline (dtp);
2347 write_character (dtp, " ", 1, 1, NODELIM);
2349 rep_ctr = 1;
2352 /* Cycle through and increment the index vector. */
2354 obj_loop:
2356 nml_carry = 1;
2357 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
2359 obj->ls[dim_i].idx += nml_carry ;
2360 nml_carry = 0;
2361 if (obj->ls[dim_i].idx > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
2363 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
2364 nml_carry = 1;
2369 /* Return a pointer beyond the furthest object accessed. */
2371 return retval;
2375 /* This is the entry function for namelist writes. It outputs the name
2376 of the namelist and iterates through the namelist by calls to
2377 nml_write_obj. The call below has dummys in the arguments used in
2378 the treatment of derived types. */
2380 void
2381 namelist_write (st_parameter_dt *dtp)
2383 namelist_info * t1, *t2, *dummy = NULL;
2384 index_type i;
2385 index_type dummy_offset = 0;
2386 char c;
2387 char * dummy_name = NULL;
2389 /* Set the delimiter for namelist output. */
2390 switch (dtp->u.p.current_unit->delim_status)
2392 case DELIM_APOSTROPHE:
2393 dtp->u.p.nml_delim = '\'';
2394 break;
2395 case DELIM_QUOTE:
2396 case DELIM_UNSPECIFIED:
2397 dtp->u.p.nml_delim = '"';
2398 break;
2399 default:
2400 dtp->u.p.nml_delim = '\0';
2403 write_character (dtp, "&", 1, 1, NODELIM);
2405 /* Write namelist name in upper case - f95 std. */
2406 for (i = 0 ;i < dtp->namelist_name_len ;i++ )
2408 c = toupper ((int) dtp->namelist_name[i]);
2409 write_character (dtp, &c, 1 ,1, NODELIM);
2412 if (dtp->u.p.ionml != NULL)
2414 t1 = dtp->u.p.ionml;
2415 while (t1 != NULL)
2417 t2 = t1;
2418 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
2422 namelist_write_newline (dtp);
2423 write_character (dtp, " /", 1, 2, NODELIM);
2426 #undef NML_DIGITS