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