]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/io/write.c
re PR libfortran/77393 (Revision r237735 changed the behavior of F0.0)
[thirdparty/gcc.git] / libgfortran / io / write.c
CommitLineData
818ab71a 1/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
6de9cd9a 2 Contributed by Andy Vaught
8b6dba81 3 Namelist output contributed by Paul Thomas
10256cbe 4 F2003 I/O support contributed by Jerry DeLisle
6de9cd9a 5
bb408e87 6This file is part of the GNU Fortran runtime library (libgfortran).
6de9cd9a
DN
7
8Libgfortran is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
748086b7 10the Free Software Foundation; either version 3, or (at your option)
6de9cd9a
DN
11any later version.
12
13Libgfortran is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
748086b7
JJ
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
6de9cd9a 26
36ae8a61 27#include "io.h"
1060d940 28#include "fbuf.h"
92cbdb68
JB
29#include "format.h"
30#include "unix.h"
1449b8cb 31#include <assert.h>
6de9cd9a 32#include <string.h>
29dc5138 33#include <ctype.h>
7984a2f0 34#include <stdlib.h>
3ae86bf4 35#include <errno.h>
6de9cd9a
DN
36#define star_fill(p, n) memset(p, '*', n)
37
3ae86bf4
JD
38typedef unsigned char uchar;
39
c7421e06
JD
40/* Helper functions for character(kind=4) internal units. These are needed
41 by write_float.def. */
42
992b0aa1 43static void
746e6327 44memcpy4 (gfc_char4_t *dest, const char *source, int k)
c7421e06
JD
45{
46 int j;
e73d3ca6 47
c7421e06 48 const char *p = source;
c7421e06 49 for (j = 0; j < k; j++)
746e6327 50 *dest++ = (gfc_char4_t) *p++;
c7421e06
JD
51}
52
53/* This include contains the heart and soul of formatted floating point. */
54#include "write_float.def"
55
3ae86bf4
JD
56/* Write out default char4. */
57
58static void
5609699a 59write_default_char4 (st_parameter_dt *dtp, const gfc_char4_t *source,
3ae86bf4
JD
60 int src_len, int w_len)
61{
62 char *p;
63 int j, k = 0;
64 gfc_char4_t c;
65 uchar d;
e73d3ca6 66
3ae86bf4
JD
67 /* Take care of preceding blanks. */
68 if (w_len > src_len)
69 {
70 k = w_len - src_len;
71 p = write_block (dtp, k);
72 if (p == NULL)
73 return;
c7421e06 74 if (is_char4_unit (dtp))
746e6327
JD
75 {
76 gfc_char4_t *p4 = (gfc_char4_t *) p;
77 memset4 (p4, ' ', k);
78 }
c7421e06
JD
79 else
80 memset (p, ' ', k);
3ae86bf4
JD
81 }
82
83 /* Get ready to handle delimiters if needed. */
105b7136 84 switch (dtp->u.p.current_unit->delim_status)
3ae86bf4
JD
85 {
86 case DELIM_APOSTROPHE:
87 d = '\'';
88 break;
89 case DELIM_QUOTE:
90 d = '"';
91 break;
92 default:
93 d = ' ';
94 break;
95 }
96
97 /* Now process the remaining characters, one at a time. */
c7421e06 98 for (j = 0; j < src_len; j++)
3ae86bf4
JD
99 {
100 c = source[j];
c7421e06 101 if (is_char4_unit (dtp))
3ae86bf4 102 {
c7421e06
JD
103 gfc_char4_t *q;
104 /* Handle delimiters if any. */
105 if (c == d && d != ' ')
106 {
107 p = write_block (dtp, 2);
108 if (p == NULL)
109 return;
110 q = (gfc_char4_t *) p;
111 *q++ = c;
112 }
113 else
114 {
115 p = write_block (dtp, 1);
116 if (p == NULL)
117 return;
118 q = (gfc_char4_t *) p;
119 }
120 *q = c;
3ae86bf4
JD
121 }
122 else
123 {
c7421e06
JD
124 /* Handle delimiters if any. */
125 if (c == d && d != ' ')
126 {
127 p = write_block (dtp, 2);
128 if (p == NULL)
129 return;
130 *p++ = (uchar) c;
131 }
132 else
133 {
134 p = write_block (dtp, 1);
135 if (p == NULL)
136 return;
137 }
138 *p = c > 255 ? '?' : (uchar) c;
3ae86bf4 139 }
3ae86bf4
JD
140 }
141}
142
143
144/* Write out UTF-8 converted from char4. */
145
146static void
147write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
148 int src_len, int w_len)
149{
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 };
7812c78c 155 int nbytes;
e73d3ca6 156 uchar buf[6], d, *q;
3ae86bf4
JD
157
158 /* Take care of preceding blanks. */
159 if (w_len > src_len)
160 {
161 k = w_len - src_len;
162 p = write_block (dtp, k);
163 if (p == NULL)
164 return;
165 memset (p, ' ', k);
166 }
167
168 /* Get ready to handle delimiters if needed. */
105b7136 169 switch (dtp->u.p.current_unit->delim_status)
3ae86bf4
JD
170 {
171 case DELIM_APOSTROPHE:
172 d = '\'';
173 break;
174 case DELIM_QUOTE:
175 d = '"';
176 break;
177 default:
178 d = ' ';
179 break;
180 }
181
182 /* Now process the remaining characters, one at a time. */
183 for (j = k; j < src_len; j++)
184 {
185 c = source[j];
186 if (c < 0x80)
187 {
188 /* Handle the delimiters if any. */
189 if (c == d && d != ' ')
190 {
191 p = write_block (dtp, 2);
192 if (p == NULL)
193 return;
194 *p++ = (uchar) c;
195 }
196 else
197 {
198 p = write_block (dtp, 1);
199 if (p == NULL)
200 return;
201 }
202 *p = (uchar) c;
203 }
204 else
205 {
206 /* Convert to UTF-8 sequence. */
207 nbytes = 1;
208 q = &buf[6];
209
210 do
211 {
212 *--q = ((c & 0x3F) | 0x80);
213 c >>= 6;
214 nbytes++;
215 }
216 while (c >= 0x3F || (c & limits[nbytes-1]));
217
218 *--q = (c | masks[nbytes-1]);
219
220 p = write_block (dtp, nbytes);
221 if (p == NULL)
222 return;
223
224 while (q < &buf[6])
225 *p++ = *q++;
226 }
227 }
228}
229
230
6de9cd9a 231void
5e805e44 232write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
6de9cd9a
DN
233{
234 int wlen;
235 char *p;
236
9355110f
JD
237 wlen = f->u.string.length < 0
238 || (f->format == FMT_G && f->u.string.length == 0)
239 ? len : f->u.string.length;
6de9cd9a 240
9e7fc6b9
JD
241#ifdef HAVE_CRLF
242 /* If this is formatted STREAM IO convert any embedded line feed characters
243 to CR_LF on systems that use that sequence for newlines. See F2003
244 Standard sections 10.6.3 and 9.9 for further information. */
245 if (is_stream_io (dtp))
246 {
247 const char crlf[] = "\r\n";
248 int i, q, bytes;
249 q = bytes = 0;
250
251 /* Write out any padding if needed. */
252 if (len < wlen)
253 {
254 p = write_block (dtp, wlen - len);
255 if (p == NULL)
256 return;
257 memset (p, ' ', wlen - len);
258 }
259
260 /* Scan the source string looking for '\n' and convert it if found. */
261 for (i = 0; i < wlen; i++)
262 {
263 if (source[i] == '\n')
264 {
265 /* Write out the previously scanned characters in the string. */
266 if (bytes > 0)
267 {
268 p = write_block (dtp, bytes);
269 if (p == NULL)
270 return;
271 memcpy (p, &source[q], bytes);
272 q += bytes;
273 bytes = 0;
274 }
275
e73d3ca6 276 /* Write out the CR_LF sequence. */
9e7fc6b9
JD
277 q++;
278 p = write_block (dtp, 2);
279 if (p == NULL)
280 return;
281 memcpy (p, crlf, 2);
282 }
283 else
284 bytes++;
285 }
286
287 /* Write out any remaining bytes if no LF was found. */
288 if (bytes > 0)
289 {
290 p = write_block (dtp, bytes);
291 if (p == NULL)
292 return;
293 memcpy (p, &source[q], bytes);
294 }
295 }
6de9cd9a
DN
296 else
297 {
9e7fc6b9
JD
298#endif
299 p = write_block (dtp, wlen);
300 if (p == NULL)
301 return;
302
c7421e06
JD
303 if (unlikely (is_char4_unit (dtp)))
304 {
746e6327 305 gfc_char4_t *p4 = (gfc_char4_t *) p;
c7421e06 306 if (wlen < len)
746e6327 307 memcpy4 (p4, source, wlen);
c7421e06
JD
308 else
309 {
746e6327
JD
310 memset4 (p4, ' ', wlen - len);
311 memcpy4 (p4 + wlen - len, source, len);
c7421e06
JD
312 }
313 return;
314 }
315
9e7fc6b9
JD
316 if (wlen < len)
317 memcpy (p, source, wlen);
318 else
319 {
320 memset (p, ' ', wlen - len);
321 memcpy (p + wlen - len, source, len);
322 }
323#ifdef HAVE_CRLF
6de9cd9a 324 }
9e7fc6b9 325#endif
6de9cd9a
DN
326}
327
cea93abb
JD
328
329/* The primary difference between write_a_char4 and write_a is that we have to
3ae86bf4
JD
330 deal with writing from the first byte of the 4-byte character and pay
331 attention to the most significant bytes. For ENCODING="default" write the
332 lowest significant byte. If the 3 most significant bytes contain
333 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
334 to the UTF-8 encoded string before writing out. */
cea93abb
JD
335
336void
337write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
338{
339 int wlen;
cea93abb
JD
340 gfc_char4_t *q;
341
342 wlen = f->u.string.length < 0
343 || (f->format == FMT_G && f->u.string.length == 0)
344 ? len : f->u.string.length;
345
346 q = (gfc_char4_t *) source;
347#ifdef HAVE_CRLF
348 /* If this is formatted STREAM IO convert any embedded line feed characters
349 to CR_LF on systems that use that sequence for newlines. See F2003
350 Standard sections 10.6.3 and 9.9 for further information. */
351 if (is_stream_io (dtp))
352 {
b495ad7f 353 const gfc_char4_t crlf[] = {0x000d,0x000a};
900e887f 354 int i, bytes;
cea93abb
JD
355 gfc_char4_t *qq;
356 bytes = 0;
357
358 /* Write out any padding if needed. */
359 if (len < wlen)
360 {
cfd648ca 361 char *p;
cea93abb
JD
362 p = write_block (dtp, wlen - len);
363 if (p == NULL)
364 return;
365 memset (p, ' ', wlen - len);
366 }
367
368 /* Scan the source string looking for '\n' and convert it if found. */
369 qq = (gfc_char4_t *) source;
370 for (i = 0; i < wlen; i++)
371 {
372 if (qq[i] == '\n')
373 {
374 /* Write out the previously scanned characters in the string. */
375 if (bytes > 0)
376 {
3ae86bf4
JD
377 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
378 write_utf8_char4 (dtp, q, bytes, 0);
379 else
380 write_default_char4 (dtp, q, bytes, 0);
cea93abb
JD
381 bytes = 0;
382 }
383
e73d3ca6 384 /* Write out the CR_LF sequence. */
3ae86bf4 385 write_default_char4 (dtp, crlf, 2, 0);
cea93abb
JD
386 }
387 else
388 bytes++;
389 }
390
391 /* Write out any remaining bytes if no LF was found. */
392 if (bytes > 0)
393 {
3ae86bf4
JD
394 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
395 write_utf8_char4 (dtp, q, bytes, 0);
396 else
397 write_default_char4 (dtp, q, bytes, 0);
cea93abb
JD
398 }
399 }
400 else
401 {
402#endif
3ae86bf4
JD
403 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
404 write_utf8_char4 (dtp, q, len, wlen);
cea93abb 405 else
3ae86bf4 406 write_default_char4 (dtp, q, len, wlen);
cea93abb
JD
407#ifdef HAVE_CRLF
408 }
409#endif
410}
411
412
32aa3bff 413static GFC_INTEGER_LARGEST
6de9cd9a
DN
414extract_int (const void *p, int len)
415{
32aa3bff 416 GFC_INTEGER_LARGEST i = 0;
6de9cd9a
DN
417
418 if (p == NULL)
419 return i;
420
421 switch (len)
422 {
423 case 1:
98cd8256
SE
424 {
425 GFC_INTEGER_1 tmp;
426 memcpy ((void *) &tmp, p, len);
427 i = tmp;
428 }
6de9cd9a
DN
429 break;
430 case 2:
98cd8256
SE
431 {
432 GFC_INTEGER_2 tmp;
433 memcpy ((void *) &tmp, p, len);
434 i = tmp;
435 }
6de9cd9a
DN
436 break;
437 case 4:
98cd8256
SE
438 {
439 GFC_INTEGER_4 tmp;
440 memcpy ((void *) &tmp, p, len);
441 i = tmp;
442 }
6de9cd9a
DN
443 break;
444 case 8:
98cd8256
SE
445 {
446 GFC_INTEGER_8 tmp;
447 memcpy ((void *) &tmp, p, len);
448 i = tmp;
449 }
32aa3bff
FXC
450 break;
451#ifdef HAVE_GFC_INTEGER_16
452 case 16:
98cd8256
SE
453 {
454 GFC_INTEGER_16 tmp;
455 memcpy ((void *) &tmp, p, len);
456 i = tmp;
457 }
6de9cd9a 458 break;
32aa3bff 459#endif
6de9cd9a 460 default:
5e805e44 461 internal_error (NULL, "bad integer kind");
6de9cd9a
DN
462 }
463
464 return i;
465}
466
999a06a0
TK
467static GFC_UINTEGER_LARGEST
468extract_uint (const void *p, int len)
469{
470 GFC_UINTEGER_LARGEST i = 0;
471
472 if (p == NULL)
473 return i;
474
475 switch (len)
476 {
477 case 1:
98cd8256
SE
478 {
479 GFC_INTEGER_1 tmp;
480 memcpy ((void *) &tmp, p, len);
481 i = (GFC_UINTEGER_1) tmp;
482 }
999a06a0
TK
483 break;
484 case 2:
98cd8256
SE
485 {
486 GFC_INTEGER_2 tmp;
487 memcpy ((void *) &tmp, p, len);
488 i = (GFC_UINTEGER_2) tmp;
489 }
999a06a0
TK
490 break;
491 case 4:
98cd8256
SE
492 {
493 GFC_INTEGER_4 tmp;
494 memcpy ((void *) &tmp, p, len);
495 i = (GFC_UINTEGER_4) tmp;
496 }
999a06a0
TK
497 break;
498 case 8:
98cd8256
SE
499 {
500 GFC_INTEGER_8 tmp;
501 memcpy ((void *) &tmp, p, len);
502 i = (GFC_UINTEGER_8) tmp;
503 }
999a06a0
TK
504 break;
505#ifdef HAVE_GFC_INTEGER_16
486024b1 506 case 10:
999a06a0 507 case 16:
98cd8256 508 {
486024b1 509 GFC_INTEGER_16 tmp = 0;
98cd8256
SE
510 memcpy ((void *) &tmp, p, len);
511 i = (GFC_UINTEGER_16) tmp;
512 }
999a06a0
TK
513 break;
514#endif
515 default:
5e805e44 516 internal_error (NULL, "bad integer kind");
999a06a0
TK
517 }
518
519 return i;
520}
521
7984a2f0 522
6de9cd9a 523void
5e805e44 524write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
6de9cd9a
DN
525{
526 char *p;
9355110f 527 int wlen;
32aa3bff 528 GFC_INTEGER_LARGEST n;
7fcb1804 529
9355110f 530 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
e73d3ca6 531
9355110f 532 p = write_block (dtp, wlen);
6de9cd9a
DN
533 if (p == NULL)
534 return;
535
6de9cd9a 536 n = extract_int (source, len);
c7421e06
JD
537
538 if (unlikely (is_char4_unit (dtp)))
539 {
540 gfc_char4_t *p4 = (gfc_char4_t *) p;
746e6327 541 memset4 (p4, ' ', wlen -1);
c7421e06
JD
542 p4[wlen - 1] = (n) ? 'T' : 'F';
543 return;
544 }
545
546 memset (p, ' ', wlen -1);
9355110f 547 p[wlen - 1] = (n) ? 'T' : 'F';
6de9cd9a
DN
548}
549
6de9cd9a
DN
550
551static void
486024b1 552write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
6de9cd9a 553{
6de9cd9a 554 int w, m, digits, nzero, nblank;
1449b8cb 555 char *p;
6de9cd9a
DN
556
557 w = f->u.integer.w;
558 m = f->u.integer.m;
559
7fcb1804 560 /* Special case: */
6de9cd9a
DN
561
562 if (m == 0 && n == 0)
563 {
564 if (w == 0)
565 w = 1;
566
5e805e44 567 p = write_block (dtp, w);
6de9cd9a
DN
568 if (p == NULL)
569 return;
c7421e06 570 if (unlikely (is_char4_unit (dtp)))
746e6327
JD
571 {
572 gfc_char4_t *p4 = (gfc_char4_t *) p;
573 memset4 (p4, ' ', w);
574 }
c7421e06
JD
575 else
576 memset (p, ' ', w);
6de9cd9a
DN
577 goto done;
578 }
579
6de9cd9a
DN
580 digits = strlen (q);
581
582 /* Select a width if none was specified. The idea here is to always
7fcb1804 583 print something. */
6de9cd9a
DN
584
585 if (w == 0)
586 w = ((digits < m) ? m : digits);
587
5e805e44 588 p = write_block (dtp, w);
6de9cd9a
DN
589 if (p == NULL)
590 return;
591
592 nzero = 0;
593 if (digits < m)
594 nzero = m - digits;
595
7fcb1804 596 /* See if things will work. */
6de9cd9a
DN
597
598 nblank = w - (nzero + digits);
599
c7421e06
JD
600 if (unlikely (is_char4_unit (dtp)))
601 {
602 gfc_char4_t *p4 = (gfc_char4_t *) p;
603 if (nblank < 0)
604 {
746e6327 605 memset4 (p4, '*', w);
c7421e06
JD
606 return;
607 }
608
609 if (!dtp->u.p.no_leading_blank)
610 {
746e6327 611 memset4 (p4, ' ', nblank);
c7421e06 612 q += nblank;
746e6327 613 memset4 (p4, '0', nzero);
c7421e06 614 q += nzero;
746e6327 615 memcpy4 (p4, q, digits);
c7421e06
JD
616 }
617 else
618 {
746e6327 619 memset4 (p4, '0', nzero);
c7421e06 620 q += nzero;
746e6327 621 memcpy4 (p4, q, digits);
c7421e06 622 q += digits;
746e6327 623 memset4 (p4, ' ', nblank);
c7421e06
JD
624 dtp->u.p.no_leading_blank = 0;
625 }
626 return;
627 }
628
6de9cd9a
DN
629 if (nblank < 0)
630 {
631 star_fill (p, w);
632 goto done;
633 }
634
5e805e44 635 if (!dtp->u.p.no_leading_blank)
29dc5138 636 {
5e805e44
JJ
637 memset (p, ' ', nblank);
638 p += nblank;
639 memset (p, '0', nzero);
640 p += nzero;
641 memcpy (p, q, digits);
29dc5138
PT
642 }
643 else
644 {
645 memset (p, '0', nzero);
646 p += nzero;
647 memcpy (p, q, digits);
648 p += digits;
649 memset (p, ' ', nblank);
5e805e44 650 dtp->u.p.no_leading_blank = 0;
29dc5138 651 }
6de9cd9a 652
f21edfd6 653 done:
6de9cd9a
DN
654 return;
655}
656
657static void
5e805e44
JJ
658write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
659 int len,
1449b8cb 660 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
6de9cd9a 661{
32aa3bff 662 GFC_INTEGER_LARGEST n = 0;
6de9cd9a 663 int w, m, digits, nsign, nzero, nblank;
1449b8cb
JJ
664 char *p;
665 const char *q;
6de9cd9a 666 sign_t sign;
1449b8cb 667 char itoa_buf[GFC_BTOA_BUF_SIZE];
6de9cd9a
DN
668
669 w = f->u.integer.w;
9355110f 670 m = f->format == FMT_G ? -1 : f->u.integer.m;
6de9cd9a
DN
671
672 n = extract_int (source, len);
673
7fcb1804 674 /* Special case: */
6de9cd9a
DN
675 if (m == 0 && n == 0)
676 {
677 if (w == 0)
678 w = 1;
679
5e805e44 680 p = write_block (dtp, w);
6de9cd9a
DN
681 if (p == NULL)
682 return;
c7421e06 683 if (unlikely (is_char4_unit (dtp)))
746e6327
JD
684 {
685 gfc_char4_t *p4 = (gfc_char4_t *) p;
686 memset4 (p4, ' ', w);
687 }
c7421e06
JD
688 else
689 memset (p, ' ', w);
6de9cd9a
DN
690 goto done;
691 }
692
5e805e44 693 sign = calculate_sign (dtp, n < 0);
6de9cd9a
DN
694 if (n < 0)
695 n = -n;
10256cbe 696 nsign = sign == S_NONE ? 0 : 1;
e73d3ca6 697
f9bfed22 698 /* conv calls itoa which sets the negative sign needed
07e9d8be
JD
699 by write_integer. The sign '+' or '-' is set below based on sign
700 calculated above, so we just point past the sign in the string
701 before proceeding to avoid double signs in corner cases.
702 (see PR38504) */
1449b8cb 703 q = conv (n, itoa_buf, sizeof (itoa_buf));
07e9d8be
JD
704 if (*q == '-')
705 q++;
6de9cd9a
DN
706
707 digits = strlen (q);
708
709 /* Select a width if none was specified. The idea here is to always
7fcb1804 710 print something. */
6de9cd9a
DN
711
712 if (w == 0)
713 w = ((digits < m) ? m : digits) + nsign;
714
5e805e44 715 p = write_block (dtp, w);
6de9cd9a
DN
716 if (p == NULL)
717 return;
718
719 nzero = 0;
720 if (digits < m)
721 nzero = m - digits;
722
7fcb1804 723 /* See if things will work. */
6de9cd9a
DN
724
725 nblank = w - (nsign + nzero + digits);
726
c7421e06
JD
727 if (unlikely (is_char4_unit (dtp)))
728 {
729 gfc_char4_t * p4 = (gfc_char4_t *) p;
730 if (nblank < 0)
731 {
746e6327 732 memset4 (p4, '*', w);
c7421e06
JD
733 goto done;
734 }
735
746e6327 736 memset4 (p4, ' ', nblank);
c7421e06
JD
737 p4 += nblank;
738
739 switch (sign)
740 {
741 case S_PLUS:
742 *p4++ = '+';
743 break;
744 case S_MINUS:
745 *p4++ = '-';
746 break;
747 case S_NONE:
748 break;
749 }
750
746e6327 751 memset4 (p4, '0', nzero);
c7421e06
JD
752 p4 += nzero;
753
746e6327 754 memcpy4 (p4, q, digits);
c7421e06
JD
755 return;
756 }
757
6de9cd9a
DN
758 if (nblank < 0)
759 {
760 star_fill (p, w);
761 goto done;
762 }
763
764 memset (p, ' ', nblank);
765 p += nblank;
766
767 switch (sign)
768 {
10256cbe 769 case S_PLUS:
6de9cd9a
DN
770 *p++ = '+';
771 break;
10256cbe 772 case S_MINUS:
6de9cd9a
DN
773 *p++ = '-';
774 break;
10256cbe 775 case S_NONE:
6de9cd9a
DN
776 break;
777 }
778
779 memset (p, '0', nzero);
780 p += nzero;
781
782 memcpy (p, q, digits);
783
f21edfd6 784 done:
6de9cd9a
DN
785 return;
786}
787
788
7fcb1804 789/* Convert unsigned octal to ascii. */
6de9cd9a 790
1449b8cb
JJ
791static const char *
792otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
6de9cd9a
DN
793{
794 char *p;
795
1449b8cb
JJ
796 assert (len >= GFC_OTOA_BUF_SIZE);
797
6de9cd9a 798 if (n == 0)
1449b8cb 799 return "0";
6de9cd9a 800
1449b8cb
JJ
801 p = buffer + GFC_OTOA_BUF_SIZE - 1;
802 *p = '\0';
6de9cd9a
DN
803
804 while (n != 0)
805 {
1449b8cb 806 *--p = '0' + (n & 7);
6de9cd9a
DN
807 n >>= 3;
808 }
809
1449b8cb 810 return p;
6de9cd9a
DN
811}
812
813
7fcb1804 814/* Convert unsigned binary to ascii. */
6de9cd9a 815
1449b8cb
JJ
816static const char *
817btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
6de9cd9a
DN
818{
819 char *p;
820
1449b8cb
JJ
821 assert (len >= GFC_BTOA_BUF_SIZE);
822
6de9cd9a 823 if (n == 0)
1449b8cb 824 return "0";
6de9cd9a 825
1449b8cb
JJ
826 p = buffer + GFC_BTOA_BUF_SIZE - 1;
827 *p = '\0';
6de9cd9a
DN
828
829 while (n != 0)
830 {
1449b8cb 831 *--p = '0' + (n & 1);
6de9cd9a
DN
832 n >>= 1;
833 }
834
1449b8cb 835 return p;
6de9cd9a
DN
836}
837
486024b1
JD
838/* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
839 to convert large reals with kind sizes that exceed the largest integer type
840 available on certain platforms. In these cases, byte by byte conversion is
841 performed. Endianess is taken into account. */
842
843/* Conversion to binary. */
844
845static const char *
846btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
847{
848 char *q;
849 int i, j;
e73d3ca6 850
486024b1
JD
851 q = buffer;
852 if (big_endian)
853 {
854 const char *p = s;
855 for (i = 0; i < len; i++)
856 {
857 char c = *p;
858
859 /* Test for zero. Needed by write_boz later. */
860 if (*p != 0)
861 *n = 1;
862
863 for (j = 0; j < 8; j++)
864 {
865 *q++ = (c & 128) ? '1' : '0';
866 c <<= 1;
867 }
868 p++;
869 }
870 }
871 else
872 {
873 const char *p = s + len - 1;
874 for (i = 0; i < len; i++)
875 {
876 char c = *p;
877
878 /* Test for zero. Needed by write_boz later. */
879 if (*p != 0)
880 *n = 1;
881
882 for (j = 0; j < 8; j++)
883 {
884 *q++ = (c & 128) ? '1' : '0';
885 c <<= 1;
886 }
887 p--;
888 }
889 }
890
891 *q = '\0';
892
893 if (*n == 0)
894 return "0";
895
e73d3ca6 896 /* Move past any leading zeros. */
486024b1
JD
897 while (*buffer == '0')
898 buffer++;
899
900 return buffer;
901
902}
903
904/* Conversion to octal. */
905
906static const char *
907otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
908{
909 char *q;
910 int i, j, k;
911 uint8_t octet;
912
913 q = buffer + GFC_OTOA_BUF_SIZE - 1;
914 *q = '\0';
915 i = k = octet = 0;
916
917 if (big_endian)
918 {
919 const char *p = s + len - 1;
920 char c = *p;
921 while (i < len)
922 {
923 /* Test for zero. Needed by write_boz later. */
924 if (*p != 0)
925 *n = 1;
926
927 for (j = 0; j < 3 && i < len; j++)
928 {
929 octet |= (c & 1) << j;
930 c >>= 1;
931 if (++k > 7)
932 {
933 i++;
934 k = 0;
935 c = *--p;
936 }
937 }
938 *--q = '0' + octet;
939 octet = 0;
940 }
941 }
942 else
943 {
944 const char *p = s;
945 char c = *p;
946 while (i < len)
947 {
948 /* Test for zero. Needed by write_boz later. */
949 if (*p != 0)
950 *n = 1;
951
952 for (j = 0; j < 3 && i < len; j++)
953 {
954 octet |= (c & 1) << j;
955 c >>= 1;
956 if (++k > 7)
957 {
958 i++;
959 k = 0;
960 c = *++p;
961 }
962 }
963 *--q = '0' + octet;
964 octet = 0;
965 }
966 }
967
968 if (*n == 0)
969 return "0";
970
e73d3ca6 971 /* Move past any leading zeros. */
486024b1
JD
972 while (*q == '0')
973 q++;
974
975 return q;
976}
977
978/* Conversion to hexidecimal. */
979
980static const char *
981ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
982{
983 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
984 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
985
986 char *q;
987 uint8_t h, l;
988 int i;
e73d3ca6 989
486024b1 990 q = buffer;
e73d3ca6 991
486024b1
JD
992 if (big_endian)
993 {
994 const char *p = s;
995 for (i = 0; i < len; i++)
996 {
997 /* Test for zero. Needed by write_boz later. */
998 if (*p != 0)
999 *n = 1;
1000
1001 h = (*p >> 4) & 0x0F;
1002 l = *p++ & 0x0F;
1003 *q++ = a[h];
1004 *q++ = a[l];
1005 }
1006 }
1007 else
1008 {
1009 const char *p = s + len - 1;
1010 for (i = 0; i < len; i++)
1011 {
1012 /* Test for zero. Needed by write_boz later. */
1013 if (*p != 0)
1014 *n = 1;
1015
1016 h = (*p >> 4) & 0x0F;
1017 l = *p-- & 0x0F;
1018 *q++ = a[h];
1019 *q++ = a[l];
1020 }
1021 }
1022
1023 *q = '\0';
e73d3ca6 1024
486024b1
JD
1025 if (*n == 0)
1026 return "0";
e73d3ca6
PT
1027
1028 /* Move past any leading zeros. */
486024b1
JD
1029 while (*buffer == '0')
1030 buffer++;
1031
1032 return buffer;
1033}
6de9cd9a 1034
f9bfed22 1035
6de9cd9a 1036void
5e805e44 1037write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
6de9cd9a 1038{
4ff62609 1039 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
6de9cd9a
DN
1040}
1041
1042
1043void
486024b1 1044write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
6de9cd9a 1045{
486024b1
JD
1046 const char *p;
1047 char itoa_buf[GFC_BTOA_BUF_SIZE];
1048 GFC_UINTEGER_LARGEST n = 0;
1049
1050 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1051 {
1052 p = btoa_big (source, itoa_buf, len, &n);
1053 write_boz (dtp, f, p, n);
1054 }
1055 else
1056 {
1057 n = extract_uint (source, len);
1058 p = btoa (n, itoa_buf, sizeof (itoa_buf));
1059 write_boz (dtp, f, p, n);
1060 }
6de9cd9a
DN
1061}
1062
1063
1064void
486024b1 1065write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
6de9cd9a 1066{
486024b1
JD
1067 const char *p;
1068 char itoa_buf[GFC_OTOA_BUF_SIZE];
1069 GFC_UINTEGER_LARGEST n = 0;
e73d3ca6 1070
486024b1
JD
1071 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1072 {
1073 p = otoa_big (source, itoa_buf, len, &n);
1074 write_boz (dtp, f, p, n);
1075 }
1076 else
1077 {
1078 n = extract_uint (source, len);
1079 p = otoa (n, itoa_buf, sizeof (itoa_buf));
1080 write_boz (dtp, f, p, n);
1081 }
6de9cd9a
DN
1082}
1083
1084void
486024b1 1085write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
6de9cd9a 1086{
486024b1
JD
1087 const char *p;
1088 char itoa_buf[GFC_XTOA_BUF_SIZE];
1089 GFC_UINTEGER_LARGEST n = 0;
1090
1091 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1092 {
1093 p = ztoa_big (source, itoa_buf, len, &n);
1094 write_boz (dtp, f, p, n);
1095 }
1096 else
1097 {
1098 n = extract_uint (source, len);
1099 p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
1100 write_boz (dtp, f, p, n);
1101 }
6de9cd9a
DN
1102}
1103
7fcb1804 1104/* Take care of the X/TR descriptor. */
6de9cd9a
DN
1105
1106void
5e805e44 1107write_x (st_parameter_dt *dtp, int len, int nspaces)
6de9cd9a
DN
1108{
1109 char *p;
1110
5e805e44 1111 p = write_block (dtp, len);
6de9cd9a
DN
1112 if (p == NULL)
1113 return;
7812c78c 1114 if (nspaces > 0 && len - nspaces >= 0)
c7421e06
JD
1115 {
1116 if (unlikely (is_char4_unit (dtp)))
746e6327
JD
1117 {
1118 gfc_char4_t *p4 = (gfc_char4_t *) p;
1119 memset4 (&p4[len - nspaces], ' ', nspaces);
1120 }
c7421e06
JD
1121 else
1122 memset (&p[len - nspaces], ' ', nspaces);
1123 }
6de9cd9a
DN
1124}
1125
1126
7fcb1804 1127/* List-directed writing. */
6de9cd9a
DN
1128
1129
7fcb1804
TS
1130/* Write a single character to the output. Returns nonzero if
1131 something goes wrong. */
6de9cd9a
DN
1132
1133static int
746e6327 1134write_char (st_parameter_dt *dtp, int c)
6de9cd9a
DN
1135{
1136 char *p;
1137
5e805e44 1138 p = write_block (dtp, 1);
6de9cd9a
DN
1139 if (p == NULL)
1140 return 1;
746e6327
JD
1141 if (unlikely (is_char4_unit (dtp)))
1142 {
1143 gfc_char4_t *p4 = (gfc_char4_t *) p;
1144 *p4 = c;
1145 return 0;
1146 }
6de9cd9a 1147
746e6327 1148 *p = (uchar) c;
6de9cd9a
DN
1149
1150 return 0;
1151}
1152
1153
7fcb1804 1154/* Write a list-directed logical value. */
d464f8e9 1155
6de9cd9a 1156static void
5e805e44 1157write_logical (st_parameter_dt *dtp, const char *source, int length)
6de9cd9a 1158{
5e805e44 1159 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
6de9cd9a
DN
1160}
1161
1162
7fcb1804 1163/* Write a list-directed integer value. */
6de9cd9a
DN
1164
1165static void
5e805e44 1166write_integer (st_parameter_dt *dtp, const char *source, int length)
6de9cd9a
DN
1167{
1168 char *p;
1169 const char *q;
1170 int digits;
d464f8e9 1171 int width;
1449b8cb 1172 char itoa_buf[GFC_ITOA_BUF_SIZE];
6de9cd9a 1173
4ff62609 1174 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
6de9cd9a 1175
d464f8e9
JB
1176 switch (length)
1177 {
1178 case 1:
1179 width = 4;
1180 break;
1181
1182 case 2:
1183 width = 6;
1184 break;
1185
1186 case 4:
1187 width = 11;
1188 break;
1189
1190 case 8:
1191 width = 20;
1192 break;
1193
1194 default:
1195 width = 0;
1196 break;
1197 }
1198
6de9cd9a
DN
1199 digits = strlen (q);
1200
5e805e44
JJ
1201 if (width < digits)
1202 width = digits;
1203 p = write_block (dtp, width);
aed6ee24
JD
1204 if (p == NULL)
1205 return;
c7421e06
JD
1206
1207 if (unlikely (is_char4_unit (dtp)))
1208 {
746e6327 1209 gfc_char4_t *p4 = (gfc_char4_t *) p;
c7421e06
JD
1210 if (dtp->u.p.no_leading_blank)
1211 {
746e6327
JD
1212 memcpy4 (p4, q, digits);
1213 memset4 (p4 + digits, ' ', width - digits);
c7421e06
JD
1214 }
1215 else
1216 {
746e6327
JD
1217 memset4 (p4, ' ', width - digits);
1218 memcpy4 (p4 + width - digits, q, digits);
c7421e06
JD
1219 }
1220 return;
1221 }
1222
5e805e44 1223 if (dtp->u.p.no_leading_blank)
29dc5138
PT
1224 {
1225 memcpy (p, q, digits);
5e805e44 1226 memset (p + digits, ' ', width - digits);
29dc5138
PT
1227 }
1228 else
1229 {
5e805e44 1230 memset (p, ' ', width - digits);
aed6ee24 1231 memcpy (p + width - digits, q, digits);
29dc5138 1232 }
6de9cd9a
DN
1233}
1234
1235
7fcb1804
TS
1236/* Write a list-directed string. We have to worry about delimiting
1237 the strings if the file has been opened in that mode. */
6de9cd9a 1238
75b2dba9
JD
1239#define DELIM 1
1240#define NODELIM 0
1241
6de9cd9a 1242static void
75b2dba9 1243write_character (st_parameter_dt *dtp, const char *source, int kind, int length, int mode)
6de9cd9a
DN
1244{
1245 int i, extra;
1246 char *p, d;
1247
75b2dba9 1248 if (mode == DELIM)
6de9cd9a 1249 {
75b2dba9
JD
1250 switch (dtp->u.p.current_unit->delim_status)
1251 {
1252 case DELIM_APOSTROPHE:
1253 d = '\'';
1254 break;
1255 case DELIM_QUOTE:
1256 d = '"';
1257 break;
1258 default:
1259 d = ' ';
1260 break;
1261 }
6de9cd9a 1262 }
75b2dba9
JD
1263 else
1264 d = ' ';
6de9cd9a 1265
cea93abb 1266 if (kind == 1)
6de9cd9a 1267 {
cea93abb
JD
1268 if (d == ' ')
1269 extra = 0;
1270 else
1271 {
1272 extra = 2;
6de9cd9a 1273
3ae86bf4
JD
1274 for (i = 0; i < length; i++)
1275 if (source[i] == d)
1276 extra++;
cea93abb 1277 }
6de9cd9a 1278
cea93abb
JD
1279 p = write_block (dtp, length + extra);
1280 if (p == NULL)
1281 return;
1282
74db2a47
JD
1283 if (unlikely (is_char4_unit (dtp)))
1284 {
1285 gfc_char4_t d4 = (gfc_char4_t) d;
1286 gfc_char4_t *p4 = (gfc_char4_t *) p;
1287
1288 if (d4 == ' ')
746e6327 1289 memcpy4 (p4, source, length);
74db2a47
JD
1290 else
1291 {
1292 *p4++ = d4;
1293
1294 for (i = 0; i < length; i++)
1295 {
1296 *p4++ = (gfc_char4_t) source[i];
1297 if (source[i] == d)
1298 *p4++ = d4;
1299 }
1300
1301 *p4 = d4;
1302 }
1303 return;
1304 }
1305
cea93abb
JD
1306 if (d == ' ')
1307 memcpy (p, source, length);
1308 else
1309 {
1310 *p++ = d;
6de9cd9a 1311
cea93abb
JD
1312 for (i = 0; i < length; i++)
1313 {
1314 *p++ = source[i];
1315 if (source[i] == d)
1316 *p++ = d;
1317 }
1318
1319 *p = d;
1320 }
1321 }
6de9cd9a
DN
1322 else
1323 {
cea93abb 1324 if (d == ' ')
6de9cd9a 1325 {
3ae86bf4
JD
1326 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1327 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1328 else
1329 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
cea93abb
JD
1330 }
1331 else
1332 {
3ae86bf4
JD
1333 p = write_block (dtp, 1);
1334 *p = d;
1335
1336 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1337 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1338 else
1339 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1340
1341 p = write_block (dtp, 1);
cea93abb
JD
1342 *p = d;
1343 }
6de9cd9a
DN
1344 }
1345}
1346
5b0e27a7
JD
1347/* Floating point helper functions. */
1348
1349#define BUF_STACK_SZ 256
1350
1351static int
1352get_precision (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1353{
1354 if (f->format != FMT_EN)
1355 return determine_precision (dtp, f, kind);
1356 else
1357 return determine_en_precision (dtp, f, source, kind);
1358}
1359
d7756960
JD
1360/* 4932 is the maximum exponent of long double and quad precision, 3
1361 extra characters for the sign, the decimal point, and the
1362 trailing null. Extra digits are added by the calling functions for
1363 requested precision. Likewise for float and double. F0 editing produces
1364 full precision output. */
1365static int
1366size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
1367{
1368 int size;
1369
1370 if (f->format == FMT_F && f->u.real.w == 0)
1371 {
1372 switch (kind)
1373 {
1374 case 4:
1375 size = 38 + 3; /* These constants shown for clarity. */
1376 break;
1377 case 8:
1378 size = 308 + 3;
1379 break;
1380 case 10:
1381 size = 4932 + 3;
1382 break;
1383 case 16:
1384 size = 4932 + 3;
1385 break;
1386 default:
1387 internal_error (&dtp->common, "bad real kind");
1388 break;
1389 }
1390 }
1391 else
1392 size = f->u.real.w + 1; /* One byte for a NULL character. */
1393
1394 return size;
1395}
1396
5b0e27a7 1397static char *
d7756960
JD
1398select_buffer (st_parameter_dt *dtp, const fnode *f, int precision,
1399 char *buf, size_t *size, int kind)
5b0e27a7
JD
1400{
1401 char *result;
d7756960
JD
1402
1403 /* The buffer needs at least one more byte to allow room for normalizing. */
1404 *size = size_from_kind (dtp, f, kind) + precision + 1;
1405
5b0e27a7
JD
1406 if (*size > BUF_STACK_SZ)
1407 result = xmalloc (*size);
1408 else
1409 result = buf;
1410 return result;
1411}
1412
1413static char *
d7756960
JD
1414select_string (st_parameter_dt *dtp, const fnode *f, char *buf, size_t *size,
1415 int kind)
5b0e27a7
JD
1416{
1417 char *result;
d7756960 1418 *size = size_from_kind (dtp, f, kind) + f->u.real.d;
5b0e27a7
JD
1419 if (*size > BUF_STACK_SZ)
1420 result = xmalloc (*size);
1421 else
1422 result = buf;
1423 return result;
1424}
1425
1426static void
1427write_float_string (st_parameter_dt *dtp, char *fstr, size_t len)
1428{
1429 char *p = write_block (dtp, len);
1430 if (p == NULL)
1431 return;
1432
1433 if (unlikely (is_char4_unit (dtp)))
1434 {
1435 gfc_char4_t *p4 = (gfc_char4_t *) p;
1436 memcpy4 (p4, fstr, len);
1437 return;
1438 }
1439 memcpy (p, fstr, len);
1440}
1441
d7756960 1442
5b0e27a7
JD
1443static void
1444write_float_0 (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1445{
1446 char buf_stack[BUF_STACK_SZ];
1447 char str_buf[BUF_STACK_SZ];
1448 char *buffer, *result;
1449 size_t buf_size, res_len;
1450
1451 /* Precision for snprintf call. */
1452 int precision = get_precision (dtp, f, source, kind);
e73d3ca6 1453
5b0e27a7 1454 /* String buffer to hold final result. */
d7756960
JD
1455 result = select_string (dtp, f, str_buf, &res_len, kind);
1456
1457 buffer = select_buffer (dtp, f, precision, buf_stack, &buf_size, kind);
1458
5b0e27a7
JD
1459 get_float_string (dtp, f, source , kind, 0, buffer,
1460 precision, buf_size, result, &res_len);
1461 write_float_string (dtp, result, res_len);
1462
1463 if (buf_size > BUF_STACK_SZ)
1464 free (buffer);
1465 if (res_len > BUF_STACK_SZ)
1466 free (result);
1467}
1468
1469void
1470write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1471{
1472 write_float_0 (dtp, f, p, len);
1473}
1474
1475
1476void
1477write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1478{
1479 write_float_0 (dtp, f, p, len);
1480}
1481
1482
1483void
1484write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1485{
1486 write_float_0 (dtp, f, p, len);
1487}
1488
1489
1490void
1491write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1492{
1493 write_float_0 (dtp, f, p, len);
1494}
1495
1496
1497void
1498write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1499{
1500 write_float_0 (dtp, f, p, len);
1501}
1502
6de9cd9a 1503
900e887f 1504/* Set an fnode to default format. */
6de9cd9a 1505
900e887f
JD
1506static void
1507set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
6de9cd9a 1508{
900e887f 1509 f->format = FMT_G;
6d56728a 1510 switch (length)
6de9cd9a 1511 {
6d56728a 1512 case 4:
a3f02fe4
JD
1513 f->u.real.w = 16;
1514 f->u.real.d = 9;
900e887f 1515 f->u.real.e = 2;
6d56728a
FXC
1516 break;
1517 case 8:
900e887f
JD
1518 f->u.real.w = 25;
1519 f->u.real.d = 17;
1520 f->u.real.e = 3;
6d56728a
FXC
1521 break;
1522 case 10:
a3f02fe4
JD
1523 f->u.real.w = 30;
1524 f->u.real.d = 21;
900e887f 1525 f->u.real.e = 4;
6d56728a
FXC
1526 break;
1527 case 16:
8d3586e4
JD
1528 /* Adjust decimal precision depending on binary precision, 106 or 113. */
1529#if GFC_REAL_16_DIGITS == 113
a3f02fe4
JD
1530 f->u.real.w = 45;
1531 f->u.real.d = 36;
900e887f 1532 f->u.real.e = 4;
8d3586e4
JD
1533#else
1534 f->u.real.w = 41;
1535 f->u.real.d = 32;
1536 f->u.real.e = 4;
1537#endif
6d56728a
FXC
1538 break;
1539 default:
5e805e44 1540 internal_error (&dtp->common, "bad real kind");
6d56728a 1541 break;
6de9cd9a 1542 }
900e887f 1543}
d785f6a3 1544
5b0e27a7
JD
1545/* Output a real number with default format.
1546 To guarantee that a binary -> decimal -> binary roundtrip conversion
1547 recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
1548 significant digits for REAL kinds 4, 8, 10, and 16, respectively.
1549 Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
1550 for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
ef6d0b67
JB
1551 Fortran standard requires outputting an extra digit when the scale
1552 factor is 1 and when the magnitude of the value is such that E
1553 editing is used. However, gfortran compensates for this, and thus
1554 for list formatted the same number of significant digits is
1555 generated both when using F and E editing. */
900e887f
JD
1556
1557void
5b0e27a7 1558write_real (st_parameter_dt *dtp, const char *source, int kind)
900e887f
JD
1559{
1560 fnode f ;
5b0e27a7
JD
1561 char buf_stack[BUF_STACK_SZ];
1562 char str_buf[BUF_STACK_SZ];
1563 char *buffer, *result;
1564 size_t buf_size, res_len;
1565 int orig_scale = dtp->u.p.scale_factor;
900e887f 1566 dtp->u.p.scale_factor = 1;
5b0e27a7
JD
1567 set_fnode_default (dtp, &f, kind);
1568
1569 /* Precision for snprintf call. */
1570 int precision = get_precision (dtp, &f, source, kind);
e73d3ca6 1571
5b0e27a7 1572 /* String buffer to hold final result. */
d7756960 1573 result = select_string (dtp, &f, str_buf, &res_len, kind);
e73d3ca6 1574
d7756960
JD
1575 /* Scratch buffer to hold final result. */
1576 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
1577
5b0e27a7
JD
1578 get_float_string (dtp, &f, source , kind, 1, buffer,
1579 precision, buf_size, result, &res_len);
1580 write_float_string (dtp, result, res_len);
1581
1582 dtp->u.p.scale_factor = orig_scale;
1583 if (buf_size > BUF_STACK_SZ)
1584 free (buffer);
1585 if (res_len > BUF_STACK_SZ)
1586 free (result);
900e887f
JD
1587}
1588
d785f6a3
JB
1589/* Similar to list formatted REAL output, for kPG0 where k > 0 we
1590 compensate for the extra digit. */
900e887f
JD
1591
1592void
5b0e27a7 1593write_real_g0 (st_parameter_dt *dtp, const char *source, int kind, int d)
900e887f 1594{
a3f02fe4 1595 fnode f;
5b0e27a7
JD
1596 char buf_stack[BUF_STACK_SZ];
1597 char str_buf[BUF_STACK_SZ];
1598 char *buffer, *result;
1599 size_t buf_size, res_len;
e73d3ca6 1600 int comp_d;
5b0e27a7
JD
1601 set_fnode_default (dtp, &f, kind);
1602
50220190
JD
1603 if (d > 0)
1604 f.u.real.d = d;
a3f02fe4
JD
1605
1606 /* Compensate for extra digits when using scale factor, d is not
1607 specified, and the magnitude is such that E editing is used. */
1608 if (dtp->u.p.scale_factor > 0 && d == 0)
1609 comp_d = 1;
1610 else
1611 comp_d = 0;
50220190 1612 dtp->u.p.g0_no_blanks = 1;
5b0e27a7
JD
1613
1614 /* Precision for snprintf call. */
1615 int precision = get_precision (dtp, &f, source, kind);
e73d3ca6 1616
5b0e27a7 1617 /* String buffer to hold final result. */
d7756960 1618 result = select_string (dtp, &f, str_buf, &res_len, kind);
5b0e27a7 1619
d7756960 1620 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
5b0e27a7
JD
1621
1622 get_float_string (dtp, &f, source , kind, comp_d, buffer,
1623 precision, buf_size, result, &res_len);
1624 write_float_string (dtp, result, res_len);
1625
50220190 1626 dtp->u.p.g0_no_blanks = 0;
5b0e27a7
JD
1627 if (buf_size > BUF_STACK_SZ)
1628 free (buffer);
1629 if (res_len > BUF_STACK_SZ)
1630 free (result);
6de9cd9a
DN
1631}
1632
1633
1634static void
5e805e44 1635write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
6de9cd9a 1636{
105b7136
JD
1637 char semi_comma =
1638 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
10256cbe 1639
5b0e27a7
JD
1640 /* Set for no blanks so we get a string result with no leading
1641 blanks. We will pad left later. */
1642 dtp->u.p.g0_no_blanks = 1;
6de9cd9a 1643
5b0e27a7
JD
1644 fnode f ;
1645 char buf_stack[BUF_STACK_SZ];
1646 char str1_buf[BUF_STACK_SZ];
1647 char str2_buf[BUF_STACK_SZ];
1648 char *buffer, *result1, *result2;
1649 size_t buf_size, res_len1, res_len2;
1650 int width, lblanks, orig_scale = dtp->u.p.scale_factor;
6de9cd9a 1651
5b0e27a7
JD
1652 dtp->u.p.scale_factor = 1;
1653 set_fnode_default (dtp, &f, kind);
e73d3ca6 1654
5b0e27a7
JD
1655 /* Set width for two values, parenthesis, and comma. */
1656 width = 2 * f.u.real.w + 3;
1657
1658 /* Set for no blanks so we get a string result with no leading
1659 blanks. We will pad left later. */
1660 dtp->u.p.g0_no_blanks = 1;
e73d3ca6 1661
5b0e27a7
JD
1662 /* Precision for snprintf call. */
1663 int precision = get_precision (dtp, &f, source, kind);
e73d3ca6 1664
5b0e27a7 1665 /* String buffers to hold final result. */
d7756960
JD
1666 result1 = select_string (dtp, &f, str1_buf, &res_len1, kind);
1667 result2 = select_string (dtp, &f, str2_buf, &res_len2, kind);
5b0e27a7 1668
d7756960 1669 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
e73d3ca6 1670
5b0e27a7
JD
1671 get_float_string (dtp, &f, source , kind, 0, buffer,
1672 precision, buf_size, result1, &res_len1);
1673 get_float_string (dtp, &f, source + size / 2 , kind, 0, buffer,
1674 precision, buf_size, result2, &res_len2);
1675 lblanks = width - res_len1 - res_len2 - 3;
e73d3ca6 1676
5b0e27a7
JD
1677 write_x (dtp, lblanks, lblanks);
1678 write_char (dtp, '(');
1679 write_float_string (dtp, result1, res_len1);
1680 write_char (dtp, semi_comma);
1681 write_float_string (dtp, result2, res_len2);
5e805e44 1682 write_char (dtp, ')');
e73d3ca6 1683
5b0e27a7
JD
1684 dtp->u.p.scale_factor = orig_scale;
1685 dtp->u.p.g0_no_blanks = 0;
1686 if (buf_size > BUF_STACK_SZ)
1687 free (buffer);
1688 if (res_len1 > BUF_STACK_SZ)
1689 free (result1);
1690 if (res_len2 > BUF_STACK_SZ)
1691 free (result2);
6de9cd9a
DN
1692}
1693
1694
7fcb1804 1695/* Write the separator between items. */
6de9cd9a
DN
1696
1697static void
5e805e44 1698write_separator (st_parameter_dt *dtp)
6de9cd9a
DN
1699{
1700 char *p;
1701
5e805e44 1702 p = write_block (dtp, options.separator_len);
6de9cd9a
DN
1703 if (p == NULL)
1704 return;
746e6327
JD
1705 if (unlikely (is_char4_unit (dtp)))
1706 {
1707 gfc_char4_t *p4 = (gfc_char4_t *) p;
1708 memcpy4 (p4, options.separator, options.separator_len);
1709 }
1710 else
1711 memcpy (p, options.separator, options.separator_len);
6de9cd9a
DN
1712}
1713
1714
7fcb1804
TS
1715/* Write an item with list formatting.
1716 TODO: handle skipping to the next record correctly, particularly
1717 with strings. */
6de9cd9a 1718
18623fae 1719static void
5e805e44
JJ
1720list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1721 size_t size)
6de9cd9a 1722{
5e805e44 1723 if (dtp->u.p.current_unit == NULL)
6de9cd9a
DN
1724 return;
1725
5e805e44 1726 if (dtp->u.p.first_item)
6de9cd9a 1727 {
5e805e44
JJ
1728 dtp->u.p.first_item = 0;
1729 write_char (dtp, ' ');
6de9cd9a
DN
1730 }
1731 else
1732 {
105b7136 1733 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
75b2dba9
JD
1734 (dtp->u.p.current_unit->delim_status != DELIM_NONE
1735 && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
105b7136 1736 write_separator (dtp);
6de9cd9a
DN
1737 }
1738
1739 switch (type)
1740 {
1741 case BT_INTEGER:
5e805e44 1742 write_integer (dtp, p, kind);
6de9cd9a
DN
1743 break;
1744 case BT_LOGICAL:
5e805e44 1745 write_logical (dtp, p, kind);
6de9cd9a
DN
1746 break;
1747 case BT_CHARACTER:
75b2dba9 1748 write_character (dtp, p, kind, size, DELIM);
6de9cd9a
DN
1749 break;
1750 case BT_REAL:
5e805e44 1751 write_real (dtp, p, kind);
6de9cd9a
DN
1752 break;
1753 case BT_COMPLEX:
5e805e44 1754 write_complex (dtp, p, kind, size);
6de9cd9a 1755 break;
e73d3ca6
PT
1756 case BT_CLASS:
1757 {
1758 int unit = dtp->u.p.current_unit->unit_number;
1759 char iotype[] = "LISTDIRECTED";
1760 gfc_charlen_type iotype_len = 12;
1761 char tmp_iomsg[IOMSG_LEN] = "";
1762 char *child_iomsg;
1763 gfc_charlen_type child_iomsg_len;
1764 int noiostat;
1765 int *child_iostat = NULL;
1766 gfc_array_i4 vlist;
1767
1768 GFC_DESCRIPTOR_DATA(&vlist) = NULL;
1769 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
1770
1771 /* Set iostat, intent(out). */
1772 noiostat = 0;
1773 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1774 dtp->common.iostat : &noiostat;
1775
1776 /* Set iomsge, intent(inout). */
1777 if (dtp->common.flags & IOPARM_HAS_IOMSG)
1778 {
1779 child_iomsg = dtp->common.iomsg;
1780 child_iomsg_len = dtp->common.iomsg_len;
1781 }
1782 else
1783 {
1784 child_iomsg = tmp_iomsg;
1785 child_iomsg_len = IOMSG_LEN;
1786 }
1787
1788 /* Call the user defined formatted WRITE procedure. */
1789 dtp->u.p.current_unit->child_dtio++;
1790 dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
1791 child_iostat, child_iomsg,
1792 iotype_len, child_iomsg_len);
1793 dtp->u.p.current_unit->child_dtio--;
1794 }
1795 break;
6de9cd9a 1796 default:
5e805e44 1797 internal_error (&dtp->common, "list_formatted_write(): Bad type");
6de9cd9a
DN
1798 }
1799
1060d940 1800 fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
5e805e44 1801 dtp->u.p.char_flag = (type == BT_CHARACTER);
6de9cd9a
DN
1802}
1803
18623fae
JB
1804
1805void
5e805e44
JJ
1806list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1807 size_t size, size_t nelems)
18623fae
JB
1808{
1809 size_t elem;
18623fae 1810 char *tmp;
cea93abb
JD
1811 size_t stride = type == BT_CHARACTER ?
1812 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
18623fae
JB
1813
1814 tmp = (char *) p;
1815
18623fae
JB
1816 /* Big loop over all the elements. */
1817 for (elem = 0; elem < nelems; elem++)
1818 {
5e805e44 1819 dtp->u.p.item_count++;
cea93abb 1820 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
18623fae
JB
1821 }
1822}
1823
29dc5138 1824/* NAMELIST OUTPUT
6de9cd9a 1825
29dc5138
PT
1826 nml_write_obj writes a namelist object to the output stream. It is called
1827 recursively for derived type components:
1828 obj = is the namelist_info for the current object.
1829 offset = the offset relative to the address held by the object for
1830 derived type arrays.
1831 base = is the namelist_info of the derived type, when obj is a
1832 component.
1833 base_name = the full name for a derived type, including qualifiers
1834 if any.
1835 The returned value is a pointer to the object beyond the last one
1836 accessed, including nested derived types. Notice that the namelist is
1837 a linear linked list of objects, including derived types and their
1838 components. A tree, of sorts, is implied by the compound names of
1839 the derived type components and this is how this function recurses through
1840 the list. */
6de9cd9a 1841
29dc5138
PT
1842/* A generous estimate of the number of characters needed to print
1843 repeat counts and indices, including commas, asterices and brackets. */
1844
1845#define NML_DIGITS 20
1846
8c8627c4
JD
1847static void
1848namelist_write_newline (st_parameter_dt *dtp)
1849{
1850 if (!is_internal_unit (dtp))
1851 {
1852#ifdef HAVE_CRLF
75b2dba9 1853 write_character (dtp, "\r\n", 1, 2, NODELIM);
8c8627c4 1854#else
75b2dba9 1855 write_character (dtp, "\n", 1, 1, NODELIM);
8c8627c4 1856#endif
94bc6c1e
JD
1857 return;
1858 }
1859
1860 if (is_array_io (dtp))
1861 {
1862 gfc_offset record;
14ca4cf8 1863 int finished;
4363c7a1
JD
1864 char *p;
1865 int length = dtp->u.p.current_unit->bytes_left;
1866
1867 p = write_block (dtp, length);
1868 if (p == NULL)
1869 return;
1870
1871 if (unlikely (is_char4_unit (dtp)))
1872 {
1873 gfc_char4_t *p4 = (gfc_char4_t *) p;
1874 memset4 (p4, ' ', length);
1875 }
1876 else
1877 memset (p, ' ', length);
94bc6c1e 1878
94bc6c1e
JD
1879 /* Now that the current record has been padded out,
1880 determine where the next record in the array is. */
1881 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
1882 &finished);
1883 if (finished)
1884 dtp->u.p.current_unit->endfile = AT_ENDFILE;
1885 else
1886 {
1887 /* Now seek to this record */
1888 record = record * dtp->u.p.current_unit->recl;
1889
7812c78c 1890 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
94bc6c1e
JD
1891 {
1892 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
1893 return;
1894 }
1895
1896 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1897 }
8c8627c4
JD
1898 }
1899 else
75b2dba9 1900 write_character (dtp, " ", 1, 1, NODELIM);
8c8627c4
JD
1901}
1902
1903
29dc5138 1904static namelist_info *
5e805e44 1905nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
29dc5138
PT
1906 namelist_info * base, char * base_name)
1907{
1908 int rep_ctr;
1909 int num;
1910 int nml_carry;
f9bfed22 1911 int len;
29dc5138
PT
1912 index_type obj_size;
1913 index_type nelem;
f9bfed22
JB
1914 size_t dim_i;
1915 size_t clen;
29dc5138 1916 index_type elem_ctr;
f9bfed22 1917 size_t obj_name_len;
9c5b1bf7 1918 void * p;
29dc5138
PT
1919 char cup;
1920 char * obj_name;
1921 char * ext_name;
9c5b1bf7 1922 char * q;
d30fe1c5 1923 size_t ext_name_len;
29dc5138
PT
1924 char rep_buff[NML_DIGITS];
1925 namelist_info * cmp;
1926 namelist_info * retval = obj->next;
88fdfd5a
JB
1927 size_t base_name_len;
1928 size_t base_var_name_len;
1929 size_t tot_len;
e73d3ca6 1930
10256cbe
JD
1931 /* Set the character to be used to separate values
1932 to a comma or semi-colon. */
1933
105b7136
JD
1934 char semi_comma =
1935 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
29dc5138
PT
1936
1937 /* Write namelist variable names in upper case. If a derived type,
1938 nothing is output. If a component, base and base_name are set. */
1939
a11930ba 1940 if (obj->type != BT_DERIVED)
b10cf173 1941 {
8c8627c4 1942 namelist_write_newline (dtp);
75b2dba9 1943 write_character (dtp, " ", 1, 1, NODELIM);
8c8627c4 1944
29dc5138
PT
1945 len = 0;
1946 if (base)
b10cf173 1947 {
f9bfed22
JB
1948 len = strlen (base->var_name);
1949 base_name_len = strlen (base_name);
1950 for (dim_i = 0; dim_i < base_name_len; dim_i++)
3bc268e6 1951 {
a4a7e2f5 1952 cup = toupper ((int) base_name[dim_i]);
75b2dba9 1953 write_character (dtp, &cup, 1, 1, NODELIM);
3bc268e6 1954 }
29dc5138 1955 }
f9bfed22
JB
1956 clen = strlen (obj->var_name);
1957 for (dim_i = len; dim_i < clen; dim_i++)
29dc5138 1958 {
a4a7e2f5 1959 cup = toupper ((int) obj->var_name[dim_i]);
9c5b1bf7
JD
1960 if (cup == '+')
1961 cup = '%';
75b2dba9 1962 write_character (dtp, &cup, 1, 1, NODELIM);
29dc5138 1963 }
75b2dba9 1964 write_character (dtp, "=", 1, 1, NODELIM);
29dc5138
PT
1965 }
1966
1967 /* Counts the number of data output on a line, including names. */
1968
1969 num = 1;
1970
1971 len = obj->len;
e5ef4b3b
JB
1972
1973 switch (obj->type)
1974 {
1975
a11930ba 1976 case BT_REAL:
e5ef4b3b
JB
1977 obj_size = size_from_real_kind (len);
1978 break;
1979
a11930ba 1980 case BT_COMPLEX:
e5ef4b3b
JB
1981 obj_size = size_from_complex_kind (len);
1982 break;
1983
a11930ba 1984 case BT_CHARACTER:
e5ef4b3b
JB
1985 obj_size = obj->string_length;
1986 break;
1987
1988 default:
e73d3ca6 1989 obj_size = len;
e5ef4b3b
JB
1990 }
1991
29dc5138
PT
1992 if (obj->var_rank)
1993 obj_size = obj->size;
1994
1995 /* Set the index vector and count the number of elements. */
1996
1997 nelem = 1;
f9bfed22 1998 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
29dc5138 1999 {
dfb55fdc
TK
2000 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
2001 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
29dc5138
PT
2002 }
2003
2004 /* Main loop to output the data held in the object. */
2005
2006 rep_ctr = 1;
2007 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
2008 {
2009
2010 /* Build the pointer to the data value. The offset is passed by
2011 recursive calls to this function for arrays of derived types.
2012 Is NULL otherwise. */
2013
2014 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
2015 p += offset;
2016
2017 /* Check for repeat counts of intrinsic types. */
2018
2019 if ((elem_ctr < (nelem - 1)) &&
a11930ba 2020 (obj->type != BT_DERIVED) &&
29dc5138
PT
2021 !memcmp (p, (void*)(p + obj_size ), obj_size ))
2022 {
2023 rep_ctr++;
2024 }
2025
2026 /* Execute a repeated output. Note the flag no_leading_blank that
2027 is used in the functions used to output the intrinsic types. */
2028
2029 else
2030 {
2031 if (rep_ctr > 1)
2032 {
d30fe1c5 2033 snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
75b2dba9 2034 write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
5e805e44 2035 dtp->u.p.no_leading_blank = 1;
29dc5138
PT
2036 }
2037 num++;
2038
420aa7b8 2039 /* Output the data, if an intrinsic type, or recurse into this
29dc5138
PT
2040 routine to treat derived types. */
2041
2042 switch (obj->type)
2043 {
2044
a11930ba 2045 case BT_INTEGER:
5e805e44 2046 write_integer (dtp, p, len);
6de9cd9a 2047 break;
29dc5138 2048
a11930ba 2049 case BT_LOGICAL:
5e805e44 2050 write_logical (dtp, p, len);
6de9cd9a 2051 break;
29dc5138 2052
a11930ba 2053 case BT_CHARACTER:
42c1e008
JD
2054 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
2055 write_character (dtp, p, 4, obj->string_length, DELIM);
2056 else
2057 write_character (dtp, p, 1, obj->string_length, DELIM);
6de9cd9a 2058 break;
29dc5138 2059
a11930ba 2060 case BT_REAL:
5e805e44 2061 write_real (dtp, p, len);
6de9cd9a 2062 break;
29dc5138 2063
a11930ba 2064 case BT_COMPLEX:
5e805e44 2065 dtp->u.p.no_leading_blank = 0;
29dc5138 2066 num++;
5e805e44 2067 write_complex (dtp, p, len, obj_size);
6de9cd9a 2068 break;
29dc5138 2069
a11930ba 2070 case BT_DERIVED:
e73d3ca6 2071 case BT_CLASS:
29dc5138
PT
2072 /* To treat a derived type, we need to build two strings:
2073 ext_name = the name, including qualifiers that prepends
420aa7b8 2074 component names in the output - passed to
29dc5138
PT
2075 nml_write_obj.
2076 obj_name = the derived type name with no qualifiers but %
420aa7b8 2077 appended. This is used to identify the
29dc5138
PT
2078 components. */
2079
2080 /* First ext_name => get length of all possible components */
e73d3ca6
PT
2081 if (obj->dtio_sub != NULL)
2082 {
2083 int unit = dtp->u.p.current_unit->unit_number;
2084 char iotype[] = "NAMELIST";
2085 gfc_charlen_type iotype_len = 8;
2086 char tmp_iomsg[IOMSG_LEN] = "";
2087 char *child_iomsg;
2088 gfc_charlen_type child_iomsg_len;
2089 int noiostat;
2090 int *child_iostat = NULL;
2091 gfc_array_i4 vlist;
2092 gfc_class list_obj;
2093 formatted_dtio dtio_ptr = (formatted_dtio)obj->dtio_sub;
2094
2095 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
2096
2097 list_obj.data = p;
2098 list_obj.vptr = obj->vtable;
2099 list_obj.len = 0;
2100
2101 /* Set iostat, intent(out). */
2102 noiostat = 0;
2103 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
2104 dtp->common.iostat : &noiostat;
2105
2106 /* Set iomsg, intent(inout). */
2107 if (dtp->common.flags & IOPARM_HAS_IOMSG)
2108 {
2109 child_iomsg = dtp->common.iomsg;
2110 child_iomsg_len = dtp->common.iomsg_len;
2111 }
2112 else
2113 {
2114 child_iomsg = tmp_iomsg;
2115 child_iomsg_len = IOMSG_LEN;
2116 }
2117 namelist_write_newline (dtp);
2118 /* Call the user defined formatted WRITE procedure. */
2119 dtp->u.p.current_unit->child_dtio++;
2120 dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
2121 child_iostat, child_iomsg,
2122 iotype_len, child_iomsg_len);
2123 dtp->u.p.current_unit->child_dtio--;
2124
2125 goto obj_loop;
2126 }
29dc5138 2127
88fdfd5a
JB
2128 base_name_len = base_name ? strlen (base_name) : 0;
2129 base_var_name_len = base ? strlen (base->var_name) : 0;
e73d3ca6 2130 ext_name_len = base_name_len + base_var_name_len
d30fe1c5 2131 + strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
92e6f3a4 2132 ext_name = xmalloc (ext_name_len);
29dc5138 2133
76b88c5f
FXC
2134 if (base_name)
2135 memcpy (ext_name, base_name, base_name_len);
88fdfd5a 2136 clen = strlen (obj->var_name + base_var_name_len);
e73d3ca6 2137 memcpy (ext_name + base_name_len,
88fdfd5a 2138 obj->var_name + base_var_name_len, clen);
e73d3ca6 2139
29dc5138
PT
2140 /* Append the qualifier. */
2141
88fdfd5a 2142 tot_len = base_name_len + clen;
f9bfed22 2143 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
29dc5138 2144 {
88fdfd5a
JB
2145 if (!dim_i)
2146 {
2147 ext_name[tot_len] = '(';
2148 tot_len++;
2149 }
e73d3ca6 2150 snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
d30fe1c5 2151 (int) obj->ls[dim_i].idx);
88fdfd5a 2152 tot_len += strlen (ext_name + tot_len);
f9bfed22 2153 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
88fdfd5a 2154 tot_len++;
29dc5138
PT
2155 }
2156
88fdfd5a 2157 ext_name[tot_len] = '\0';
9c5b1bf7
JD
2158 for (q = ext_name; *q; q++)
2159 if (*q == '+')
2160 *q = '%';
88fdfd5a 2161
29dc5138
PT
2162 /* Now obj_name. */
2163
2164 obj_name_len = strlen (obj->var_name) + 1;
92e6f3a4 2165 obj_name = xmalloc (obj_name_len + 1);
88fdfd5a
JB
2166 memcpy (obj_name, obj->var_name, obj_name_len-1);
2167 memcpy (obj_name + obj_name_len-1, "%", 2);
29dc5138
PT
2168
2169 /* Now loop over the components. Update the component pointer
2170 with the return value from nml_write_obj => this loop jumps
2171 past nested derived types. */
2172
2173 for (cmp = obj->next;
2174 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
2175 cmp = retval)
2176 {
5e805e44
JJ
2177 retval = nml_write_obj (dtp, cmp,
2178 (index_type)(p - obj->mem_pos),
29dc5138
PT
2179 obj, ext_name);
2180 }
2181
bb408e87
JB
2182 free (obj_name);
2183 free (ext_name);
29dc5138
PT
2184 goto obj_loop;
2185
6de9cd9a 2186 default:
5e805e44 2187 internal_error (&dtp->common, "Bad type for namelist write");
6de9cd9a 2188 }
29dc5138 2189
10256cbe
JD
2190 /* Reset the leading blank suppression, write a comma (or semi-colon)
2191 and, if 5 values have been output, write a newline and advance
2192 to column 2. Reset the repeat counter. */
29dc5138 2193
5e805e44 2194 dtp->u.p.no_leading_blank = 0;
75b2dba9
JD
2195 if (obj->type == BT_CHARACTER)
2196 {
2197 if (dtp->u.p.nml_delim != '\0')
2198 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2199 }
2200 else
2201 write_character (dtp, &semi_comma, 1, 1, NODELIM);
b10cf173
RS
2202 if (num > 5)
2203 {
2204 num = 0;
75b2dba9
JD
2205 if (dtp->u.p.nml_delim == '\0')
2206 write_character (dtp, &semi_comma, 1, 1, NODELIM);
8c8627c4 2207 namelist_write_newline (dtp);
75b2dba9 2208 write_character (dtp, " ", 1, 1, NODELIM);
29dc5138
PT
2209 }
2210 rep_ctr = 1;
2211 }
2212
2213 /* Cycle through and increment the index vector. */
2214
2215obj_loop:
2216
75b2dba9
JD
2217 nml_carry = 1;
2218 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
2219 {
2220 obj->ls[dim_i].idx += nml_carry ;
2221 nml_carry = 0;
2222 if (obj->ls[dim_i].idx > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
2223 {
2224 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
2225 nml_carry = 1;
2226 }
2227 }
29dc5138
PT
2228 }
2229
2230 /* Return a pointer beyond the furthest object accessed. */
2231
2232 return retval;
2233}
2234
8c8627c4 2235
29dc5138 2236/* This is the entry function for namelist writes. It outputs the name
420aa7b8
AJ
2237 of the namelist and iterates through the namelist by calls to
2238 nml_write_obj. The call below has dummys in the arguments used in
29dc5138
PT
2239 the treatment of derived types. */
2240
2241void
5e805e44 2242namelist_write (st_parameter_dt *dtp)
29dc5138
PT
2243{
2244 namelist_info * t1, *t2, *dummy = NULL;
2245 index_type i;
2246 index_type dummy_offset = 0;
2247 char c;
2248 char * dummy_name = NULL;
29dc5138
PT
2249
2250 /* Set the delimiter for namelist output. */
75b2dba9
JD
2251 switch (dtp->u.p.current_unit->delim_status)
2252 {
2253 case DELIM_APOSTROPHE:
2254 dtp->u.p.nml_delim = '\'';
2255 break;
2256 case DELIM_QUOTE:
2257 case DELIM_UNSPECIFIED:
2258 dtp->u.p.nml_delim = '"';
2259 break;
2260 default:
2261 dtp->u.p.nml_delim = '\0';
2262 }
105b7136 2263
75b2dba9 2264 write_character (dtp, "&", 1, 1, NODELIM);
29dc5138
PT
2265
2266 /* Write namelist name in upper case - f95 std. */
5e805e44 2267 for (i = 0 ;i < dtp->namelist_name_len ;i++ )
29dc5138 2268 {
a4a7e2f5 2269 c = toupper ((int) dtp->namelist_name[i]);
75b2dba9 2270 write_character (dtp, &c, 1 ,1, NODELIM);
5e805e44 2271 }
29dc5138 2272
5e805e44 2273 if (dtp->u.p.ionml != NULL)
29dc5138 2274 {
5e805e44 2275 t1 = dtp->u.p.ionml;
29dc5138
PT
2276 while (t1 != NULL)
2277 {
2278 t2 = t1;
5e805e44 2279 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
b10cf173
RS
2280 }
2281 }
0be72e3a 2282
8c8627c4 2283 namelist_write_newline (dtp);
75b2dba9 2284 write_character (dtp, " /", 1, 2, NODELIM);
6de9cd9a 2285}
29dc5138
PT
2286
2287#undef NML_DIGITS