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