]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/io/write.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / io / write.c
1 /* Copyright (C) 2002-2022 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 Namelist output contributed by Paul Thomas
4 F2003 I/O support contributed by Jerry DeLisle
5
6 This file is part of the GNU Fortran runtime library (libgfortran).
7
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
26
27 #include "io.h"
28 #include "fbuf.h"
29 #include "format.h"
30 #include "unix.h"
31 #include <assert.h>
32 #include <string.h>
33
34 #define star_fill(p, n) memset(p, '*', n)
35
36 typedef unsigned char uchar;
37
38 /* Helper functions for character(kind=4) internal units. These are needed
39 by write_float.def. */
40
41 static void
42 memcpy4 (gfc_char4_t *dest, const char *source, int k)
43 {
44 int j;
45
46 const char *p = source;
47 for (j = 0; j < k; j++)
48 *dest++ = (gfc_char4_t) *p++;
49 }
50
51 /* This include contains the heart and soul of formatted floating point. */
52 #include "write_float.def"
53
54 /* Write out default char4. */
55
56 static void
57 write_default_char4 (st_parameter_dt *dtp, const gfc_char4_t *source,
58 int src_len, int w_len)
59 {
60 char *p;
61 int j, k = 0;
62 gfc_char4_t c;
63 uchar d;
64
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;
72 if (is_char4_unit (dtp))
73 {
74 gfc_char4_t *p4 = (gfc_char4_t *) p;
75 memset4 (p4, ' ', k);
76 }
77 else
78 memset (p, ' ', k);
79 }
80
81 /* Get ready to handle delimiters if needed. */
82 switch (dtp->u.p.current_unit->delim_status)
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. */
96 for (j = 0; j < src_len; j++)
97 {
98 c = source[j];
99 if (is_char4_unit (dtp))
100 {
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;
119 }
120 else
121 {
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;
137 }
138 }
139 }
140
141
142 /* Write out UTF-8 converted from char4. */
143
144 static void
145 write_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 };
153 int nbytes;
154 uchar buf[6], d, *q;
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. */
167 switch (dtp->u.p.current_unit->delim_status)
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
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
236 static void
237 write_check_cc (st_parameter_dt *dtp, const char **source, size_t *alloc_len)
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
312 static char *
313 write_cc (st_parameter_dt *dtp, char *p, size_t *source_len)
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
361 void
362
363 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, size_t len)
364 {
365 size_t wlen;
366 char *p;
367
368 wlen = f->u.string.length < 0
369 || (f->format == FMT_G && f->u.string.length == 0)
370 ? len : (size_t) f->u.string.length;
371
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 size_t 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 (size_t 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
407 /* Write out the CR_LF sequence. */
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 }
427 else
428 {
429 #endif
430 if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
431 write_check_cc (dtp, &source, &wlen);
432
433 p = write_block (dtp, wlen);
434 if (p == NULL)
435 return;
436
437 if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
438 p = write_cc (dtp, p, &wlen);
439
440 if (unlikely (is_char4_unit (dtp)))
441 {
442 gfc_char4_t *p4 = (gfc_char4_t *) p;
443 if (wlen < len)
444 memcpy4 (p4, source, wlen);
445 else
446 {
447 memset4 (p4, ' ', wlen - len);
448 memcpy4 (p4 + wlen - len, source, len);
449 }
450 return;
451 }
452
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
461 }
462 #endif
463 }
464
465
466 /* The primary difference between write_a_char4 and write_a is that we have to
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. */
472
473 void
474 write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, size_t len)
475 {
476 size_t wlen;
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 : (size_t) 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 {
490 const gfc_char4_t crlf[] = {0x000d,0x000a};
491 size_t bytes;
492 gfc_char4_t *qq;
493 bytes = 0;
494
495 /* Write out any padding if needed. */
496 if (len < wlen)
497 {
498 char *p;
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 (size_t 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 {
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);
518 bytes = 0;
519 }
520
521 /* Write out the CR_LF sequence. */
522 write_default_char4 (dtp, crlf, 2, 0);
523 }
524 else
525 bytes++;
526 }
527
528 /* Write out any remaining bytes if no LF was found. */
529 if (bytes > 0)
530 {
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);
535 }
536 }
537 else
538 {
539 #endif
540 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
541 write_utf8_char4 (dtp, q, len, wlen);
542 else
543 write_default_char4 (dtp, q, len, wlen);
544 #ifdef HAVE_CRLF
545 }
546 #endif
547 }
548
549
550 static GFC_INTEGER_LARGEST
551 extract_int (const void *p, int len)
552 {
553 GFC_INTEGER_LARGEST i = 0;
554
555 if (p == NULL)
556 return i;
557
558 switch (len)
559 {
560 case 1:
561 {
562 GFC_INTEGER_1 tmp;
563 memcpy ((void *) &tmp, p, len);
564 i = tmp;
565 }
566 break;
567 case 2:
568 {
569 GFC_INTEGER_2 tmp;
570 memcpy ((void *) &tmp, p, len);
571 i = tmp;
572 }
573 break;
574 case 4:
575 {
576 GFC_INTEGER_4 tmp;
577 memcpy ((void *) &tmp, p, len);
578 i = tmp;
579 }
580 break;
581 case 8:
582 {
583 GFC_INTEGER_8 tmp;
584 memcpy ((void *) &tmp, p, len);
585 i = tmp;
586 }
587 break;
588 #ifdef HAVE_GFC_INTEGER_16
589 case 16:
590 {
591 GFC_INTEGER_16 tmp;
592 memcpy ((void *) &tmp, p, len);
593 i = tmp;
594 }
595 break;
596 #endif
597 default:
598 internal_error (NULL, "bad integer kind");
599 }
600
601 return i;
602 }
603
604 static GFC_UINTEGER_LARGEST
605 extract_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:
615 {
616 GFC_INTEGER_1 tmp;
617 memcpy ((void *) &tmp, p, len);
618 i = (GFC_UINTEGER_1) tmp;
619 }
620 break;
621 case 2:
622 {
623 GFC_INTEGER_2 tmp;
624 memcpy ((void *) &tmp, p, len);
625 i = (GFC_UINTEGER_2) tmp;
626 }
627 break;
628 case 4:
629 {
630 GFC_INTEGER_4 tmp;
631 memcpy ((void *) &tmp, p, len);
632 i = (GFC_UINTEGER_4) tmp;
633 }
634 break;
635 case 8:
636 {
637 GFC_INTEGER_8 tmp;
638 memcpy ((void *) &tmp, p, len);
639 i = (GFC_UINTEGER_8) tmp;
640 }
641 break;
642 #ifdef HAVE_GFC_INTEGER_16
643 case 10:
644 case 16:
645 {
646 GFC_INTEGER_16 tmp = 0;
647 memcpy ((void *) &tmp, p, len);
648 i = (GFC_UINTEGER_16) tmp;
649 }
650 break;
651 #endif
652 default:
653 internal_error (NULL, "bad integer kind");
654 }
655
656 return i;
657 }
658
659
660 void
661 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
662 {
663 char *p;
664 int wlen;
665 GFC_INTEGER_LARGEST n;
666
667 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
668
669 p = write_block (dtp, wlen);
670 if (p == NULL)
671 return;
672
673 n = extract_int (source, len);
674
675 if (unlikely (is_char4_unit (dtp)))
676 {
677 gfc_char4_t *p4 = (gfc_char4_t *) p;
678 memset4 (p4, ' ', wlen -1);
679 p4[wlen - 1] = (n) ? 'T' : 'F';
680 return;
681 }
682
683 memset (p, ' ', wlen -1);
684 p[wlen - 1] = (n) ? 'T' : 'F';
685 }
686
687 static void
688 write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len)
689 {
690 int w, m, digits, nzero, nblank;
691 char *p;
692
693 w = f->u.integer.w;
694 m = f->u.integer.m;
695
696 /* Special case: */
697
698 if (m == 0 && n == 0)
699 {
700 if (w == 0)
701 w = 1;
702
703 p = write_block (dtp, w);
704 if (p == NULL)
705 return;
706 if (unlikely (is_char4_unit (dtp)))
707 {
708 gfc_char4_t *p4 = (gfc_char4_t *) p;
709 memset4 (p4, ' ', w);
710 }
711 else
712 memset (p, ' ', w);
713 goto done;
714 }
715
716 digits = strlen (q);
717
718 /* Select a width if none was specified. The idea here is to always
719 print something. */
720
721 if (w == DEFAULT_WIDTH)
722 w = default_width_for_integer (len);
723
724 if (w == 0)
725 w = ((digits < m) ? m : digits);
726
727 p = write_block (dtp, w);
728 if (p == NULL)
729 return;
730
731 nzero = 0;
732 if (digits < m)
733 nzero = m - digits;
734
735 /* See if things will work. */
736
737 nblank = w - (nzero + digits);
738
739 if (unlikely (is_char4_unit (dtp)))
740 {
741 gfc_char4_t *p4 = (gfc_char4_t *) p;
742 if (nblank < 0)
743 {
744 memset4 (p4, '*', w);
745 return;
746 }
747
748 if (!dtp->u.p.no_leading_blank)
749 {
750 memset4 (p4, ' ', nblank);
751 q += nblank;
752 memset4 (p4, '0', nzero);
753 q += nzero;
754 memcpy4 (p4, q, digits);
755 }
756 else
757 {
758 memset4 (p4, '0', nzero);
759 q += nzero;
760 memcpy4 (p4, q, digits);
761 q += digits;
762 memset4 (p4, ' ', nblank);
763 dtp->u.p.no_leading_blank = 0;
764 }
765 return;
766 }
767
768 if (nblank < 0)
769 {
770 star_fill (p, w);
771 goto done;
772 }
773
774 if (!dtp->u.p.no_leading_blank)
775 {
776 memset (p, ' ', nblank);
777 p += nblank;
778 memset (p, '0', nzero);
779 p += nzero;
780 memcpy (p, q, digits);
781 }
782 else
783 {
784 memset (p, '0', nzero);
785 p += nzero;
786 memcpy (p, q, digits);
787 p += digits;
788 memset (p, ' ', nblank);
789 dtp->u.p.no_leading_blank = 0;
790 }
791
792 done:
793 return;
794 }
795
796 static void
797 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
798 int len)
799 {
800 GFC_INTEGER_LARGEST n = 0;
801 GFC_UINTEGER_LARGEST absn;
802 int w, m, digits, nsign, nzero, nblank;
803 char *p;
804 const char *q;
805 sign_t sign;
806 char itoa_buf[GFC_BTOA_BUF_SIZE];
807
808 w = f->u.integer.w;
809 m = f->format == FMT_G ? -1 : f->u.integer.m;
810
811 n = extract_int (source, len);
812
813 /* Special case: */
814 if (m == 0 && n == 0)
815 {
816 if (w == 0)
817 w = 1;
818
819 p = write_block (dtp, w);
820 if (p == NULL)
821 return;
822 if (unlikely (is_char4_unit (dtp)))
823 {
824 gfc_char4_t *p4 = (gfc_char4_t *) p;
825 memset4 (p4, ' ', w);
826 }
827 else
828 memset (p, ' ', w);
829 goto done;
830 }
831
832 sign = calculate_sign (dtp, n < 0);
833 if (n < 0)
834 /* Use unsigned to protect from overflow. */
835 absn = -(GFC_UINTEGER_LARGEST) n;
836 else
837 absn = n;
838 nsign = sign == S_NONE ? 0 : 1;
839
840 /* gfc_itoa() converts the nonnegative value to decimal representation. */
841 q = gfc_itoa (absn, itoa_buf, sizeof (itoa_buf));
842 digits = strlen (q);
843
844 /* Select a width if none was specified. The idea here is to always
845 print something. */
846 if (w == DEFAULT_WIDTH)
847 w = default_width_for_integer (len);
848
849 if (w == 0)
850 w = ((digits < m) ? m : digits) + nsign;
851
852 p = write_block (dtp, w);
853 if (p == NULL)
854 return;
855
856 nzero = 0;
857 if (digits < m)
858 nzero = m - digits;
859
860 /* See if things will work. */
861
862 nblank = w - (nsign + nzero + digits);
863
864 if (unlikely (is_char4_unit (dtp)))
865 {
866 gfc_char4_t *p4 = (gfc_char4_t *)p;
867 if (nblank < 0)
868 {
869 memset4 (p4, '*', w);
870 goto done;
871 }
872
873 if (!dtp->u.p.namelist_mode)
874 {
875 memset4 (p4, ' ', nblank);
876 p4 += nblank;
877 }
878
879 switch (sign)
880 {
881 case S_PLUS:
882 *p4++ = '+';
883 break;
884 case S_MINUS:
885 *p4++ = '-';
886 break;
887 case S_NONE:
888 break;
889 }
890
891 memset4 (p4, '0', nzero);
892 p4 += nzero;
893
894 memcpy4 (p4, q, digits);
895 return;
896
897 if (dtp->u.p.namelist_mode)
898 {
899 p4 += digits;
900 memset4 (p4, ' ', nblank);
901 }
902 }
903
904 if (nblank < 0)
905 {
906 star_fill (p, w);
907 goto done;
908 }
909
910 if (!dtp->u.p.namelist_mode)
911 {
912 memset (p, ' ', nblank);
913 p += nblank;
914 }
915
916 switch (sign)
917 {
918 case S_PLUS:
919 *p++ = '+';
920 break;
921 case S_MINUS:
922 *p++ = '-';
923 break;
924 case S_NONE:
925 break;
926 }
927
928 memset (p, '0', nzero);
929 p += nzero;
930
931 memcpy (p, q, digits);
932
933 if (dtp->u.p.namelist_mode)
934 {
935 p += digits;
936 memset (p, ' ', nblank);
937 }
938
939 done:
940 return;
941 }
942
943
944 /* Convert hexadecimal to ASCII. */
945
946 static const char *
947 xtoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
948 {
949 int digit;
950 char *p;
951
952 assert (len >= GFC_XTOA_BUF_SIZE);
953
954 if (n == 0)
955 return "0";
956
957 p = buffer + GFC_XTOA_BUF_SIZE - 1;
958 *p = '\0';
959
960 while (n != 0)
961 {
962 digit = n & 0xF;
963 if (digit > 9)
964 digit += 'A' - '0' - 10;
965
966 *--p = '0' + digit;
967 n >>= 4;
968 }
969
970 return p;
971 }
972
973
974 /* Convert unsigned octal to ASCII. */
975
976 static const char *
977 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
978 {
979 char *p;
980
981 assert (len >= GFC_OTOA_BUF_SIZE);
982
983 if (n == 0)
984 return "0";
985
986 p = buffer + GFC_OTOA_BUF_SIZE - 1;
987 *p = '\0';
988
989 while (n != 0)
990 {
991 *--p = '0' + (n & 7);
992 n >>= 3;
993 }
994
995 return p;
996 }
997
998
999 /* Convert unsigned binary to ASCII. */
1000
1001 static const char *
1002 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
1003 {
1004 char *p;
1005
1006 assert (len >= GFC_BTOA_BUF_SIZE);
1007
1008 if (n == 0)
1009 return "0";
1010
1011 p = buffer + GFC_BTOA_BUF_SIZE - 1;
1012 *p = '\0';
1013
1014 while (n != 0)
1015 {
1016 *--p = '0' + (n & 1);
1017 n >>= 1;
1018 }
1019
1020 return p;
1021 }
1022
1023 /* The following three functions, btoa_big, otoa_big, and xtoa_big, are needed
1024 to convert large reals with kind sizes that exceed the largest integer type
1025 available on certain platforms. In these cases, byte by byte conversion is
1026 performed. Endianess is taken into account. */
1027
1028 /* Conversion to binary. */
1029
1030 static const char *
1031 btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
1032 {
1033 char *q;
1034 int i, j;
1035
1036 q = buffer;
1037 if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
1038 {
1039 const char *p = s;
1040 for (i = 0; i < len; i++)
1041 {
1042 char c = *p;
1043
1044 /* Test for zero. Needed by write_boz later. */
1045 if (*p != 0)
1046 *n = 1;
1047
1048 for (j = 0; j < 8; j++)
1049 {
1050 *q++ = (c & 128) ? '1' : '0';
1051 c <<= 1;
1052 }
1053 p++;
1054 }
1055 }
1056 else
1057 {
1058 const char *p = s + len - 1;
1059 for (i = 0; i < len; i++)
1060 {
1061 char c = *p;
1062
1063 /* Test for zero. Needed by write_boz later. */
1064 if (*p != 0)
1065 *n = 1;
1066
1067 for (j = 0; j < 8; j++)
1068 {
1069 *q++ = (c & 128) ? '1' : '0';
1070 c <<= 1;
1071 }
1072 p--;
1073 }
1074 }
1075
1076 if (*n == 0)
1077 return "0";
1078
1079 /* Move past any leading zeros. */
1080 while (*buffer == '0')
1081 buffer++;
1082
1083 return buffer;
1084
1085 }
1086
1087 /* Conversion to octal. */
1088
1089 static const char *
1090 otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
1091 {
1092 char *q;
1093 int i, j, k;
1094 uint8_t octet;
1095
1096 q = buffer + GFC_OTOA_BUF_SIZE - 1;
1097 *q = '\0';
1098 i = k = octet = 0;
1099
1100 if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
1101 {
1102 const char *p = s + len - 1;
1103 char c = *p;
1104 while (i < len)
1105 {
1106 /* Test for zero. Needed by write_boz later. */
1107 if (*p != 0)
1108 *n = 1;
1109
1110 for (j = 0; j < 3 && i < len; j++)
1111 {
1112 octet |= (c & 1) << j;
1113 c >>= 1;
1114 if (++k > 7)
1115 {
1116 i++;
1117 k = 0;
1118 c = *--p;
1119 }
1120 }
1121 *--q = '0' + octet;
1122 octet = 0;
1123 }
1124 }
1125 else
1126 {
1127 const char *p = s;
1128 char c = *p;
1129 while (i < len)
1130 {
1131 /* Test for zero. Needed by write_boz later. */
1132 if (*p != 0)
1133 *n = 1;
1134
1135 for (j = 0; j < 3 && i < len; j++)
1136 {
1137 octet |= (c & 1) << j;
1138 c >>= 1;
1139 if (++k > 7)
1140 {
1141 i++;
1142 k = 0;
1143 c = *++p;
1144 }
1145 }
1146 *--q = '0' + octet;
1147 octet = 0;
1148 }
1149 }
1150
1151 if (*n == 0)
1152 return "0";
1153
1154 /* Move past any leading zeros. */
1155 while (*q == '0')
1156 q++;
1157
1158 return q;
1159 }
1160
1161 /* Conversion to hexadecimal. */
1162
1163 static const char *
1164 xtoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
1165 {
1166 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
1167 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
1168
1169 char *q;
1170 uint8_t h, l;
1171 int i;
1172
1173 q = buffer;
1174
1175 if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
1176 {
1177 const char *p = s;
1178 for (i = 0; i < len; i++)
1179 {
1180 /* Test for zero. Needed by write_boz later. */
1181 if (*p != 0)
1182 *n = 1;
1183
1184 h = (*p >> 4) & 0x0F;
1185 l = *p++ & 0x0F;
1186 *q++ = a[h];
1187 *q++ = a[l];
1188 }
1189 }
1190 else
1191 {
1192 const char *p = s + len - 1;
1193 for (i = 0; i < len; i++)
1194 {
1195 /* Test for zero. Needed by write_boz later. */
1196 if (*p != 0)
1197 *n = 1;
1198
1199 h = (*p >> 4) & 0x0F;
1200 l = *p-- & 0x0F;
1201 *q++ = a[h];
1202 *q++ = a[l];
1203 }
1204 }
1205
1206 /* write_z, which calls xtoa_big, is called from transfer.c,
1207 formatted_transfer_scalar_write. There it is passed the kind as
1208 argument, which means a maximum of 16. The buffer is large
1209 enough, but the compiler does not know that, so shut up the
1210 warning here. */
1211 #pragma GCC diagnostic push
1212 #pragma GCC diagnostic ignored "-Wstringop-overflow"
1213 *q = '\0';
1214 #pragma GCC diagnostic pop
1215
1216 if (*n == 0)
1217 return "0";
1218
1219 /* Move past any leading zeros. */
1220 while (*buffer == '0')
1221 buffer++;
1222
1223 return buffer;
1224 }
1225
1226
1227 void
1228 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1229 {
1230 write_decimal (dtp, f, p, len);
1231 }
1232
1233
1234 void
1235 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1236 {
1237 const char *p;
1238 char itoa_buf[GFC_BTOA_BUF_SIZE];
1239 GFC_UINTEGER_LARGEST n = 0;
1240
1241 /* Ensure we end up with a null terminated string. */
1242 memset(itoa_buf, '\0', GFC_BTOA_BUF_SIZE);
1243
1244 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1245 {
1246 p = btoa_big (source, itoa_buf, len, &n);
1247 write_boz (dtp, f, p, n, len);
1248 }
1249 else
1250 {
1251 n = extract_uint (source, len);
1252 p = btoa (n, itoa_buf, sizeof (itoa_buf));
1253 write_boz (dtp, f, p, n, len);
1254 }
1255 }
1256
1257
1258 void
1259 write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1260 {
1261 const char *p;
1262 char itoa_buf[GFC_OTOA_BUF_SIZE];
1263 GFC_UINTEGER_LARGEST n = 0;
1264
1265 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1266 {
1267 p = otoa_big (source, itoa_buf, len, &n);
1268 write_boz (dtp, f, p, n, len);
1269 }
1270 else
1271 {
1272 n = extract_uint (source, len);
1273 p = otoa (n, itoa_buf, sizeof (itoa_buf));
1274 write_boz (dtp, f, p, n, len);
1275 }
1276 }
1277
1278 void
1279 write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
1280 {
1281 const char *p;
1282 char itoa_buf[GFC_XTOA_BUF_SIZE];
1283 GFC_UINTEGER_LARGEST n = 0;
1284
1285 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
1286 {
1287 p = xtoa_big (source, itoa_buf, len, &n);
1288 write_boz (dtp, f, p, n, len);
1289 }
1290 else
1291 {
1292 n = extract_uint (source, len);
1293 p = xtoa (n, itoa_buf, sizeof (itoa_buf));
1294 write_boz (dtp, f, p, n, len);
1295 }
1296 }
1297
1298 /* Take care of the X/TR descriptor. */
1299
1300 void
1301 write_x (st_parameter_dt *dtp, int len, int nspaces)
1302 {
1303 char *p;
1304
1305 p = write_block (dtp, len);
1306 if (p == NULL)
1307 return;
1308 if (nspaces > 0 && len - nspaces >= 0)
1309 {
1310 if (unlikely (is_char4_unit (dtp)))
1311 {
1312 gfc_char4_t *p4 = (gfc_char4_t *) p;
1313 memset4 (&p4[len - nspaces], ' ', nspaces);
1314 }
1315 else
1316 memset (&p[len - nspaces], ' ', nspaces);
1317 }
1318 }
1319
1320
1321 /* List-directed writing. */
1322
1323
1324 /* Write a single character to the output. Returns nonzero if
1325 something goes wrong. */
1326
1327 static int
1328 write_char (st_parameter_dt *dtp, int c)
1329 {
1330 char *p;
1331
1332 p = write_block (dtp, 1);
1333 if (p == NULL)
1334 return 1;
1335 if (unlikely (is_char4_unit (dtp)))
1336 {
1337 gfc_char4_t *p4 = (gfc_char4_t *) p;
1338 *p4 = c;
1339 return 0;
1340 }
1341
1342 *p = (uchar) c;
1343
1344 return 0;
1345 }
1346
1347
1348 /* Write a list-directed logical value. */
1349
1350 static void
1351 write_logical (st_parameter_dt *dtp, const char *source, int length)
1352 {
1353 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
1354 }
1355
1356
1357 /* Write a list-directed integer value. */
1358
1359 static void
1360 write_integer (st_parameter_dt *dtp, const char *source, int kind)
1361 {
1362 int width;
1363 fnode f;
1364
1365 switch (kind)
1366 {
1367 case 1:
1368 width = 4;
1369 break;
1370
1371 case 2:
1372 width = 6;
1373 break;
1374
1375 case 4:
1376 width = 11;
1377 break;
1378
1379 case 8:
1380 width = 20;
1381 break;
1382
1383 case 16:
1384 width = 40;
1385 break;
1386
1387 default:
1388 width = 0;
1389 break;
1390 }
1391 f.u.integer.w = width;
1392 f.u.integer.m = -1;
1393 f.format = FMT_NONE;
1394 write_decimal (dtp, &f, source, kind);
1395 }
1396
1397
1398 /* Write a list-directed string. We have to worry about delimiting
1399 the strings if the file has been opened in that mode. */
1400
1401 #define DELIM 1
1402 #define NODELIM 0
1403
1404 static void
1405 write_character (st_parameter_dt *dtp, const char *source, int kind, size_t length, int mode)
1406 {
1407 size_t extra;
1408 char *p, d;
1409
1410 if (mode == DELIM)
1411 {
1412 switch (dtp->u.p.current_unit->delim_status)
1413 {
1414 case DELIM_APOSTROPHE:
1415 d = '\'';
1416 break;
1417 case DELIM_QUOTE:
1418 d = '"';
1419 break;
1420 default:
1421 d = ' ';
1422 break;
1423 }
1424 }
1425 else
1426 d = ' ';
1427
1428 if (kind == 1)
1429 {
1430 if (d == ' ')
1431 extra = 0;
1432 else
1433 {
1434 extra = 2;
1435
1436 for (size_t i = 0; i < length; i++)
1437 if (source[i] == d)
1438 extra++;
1439 }
1440
1441 p = write_block (dtp, length + extra);
1442 if (p == NULL)
1443 return;
1444
1445 if (unlikely (is_char4_unit (dtp)))
1446 {
1447 gfc_char4_t d4 = (gfc_char4_t) d;
1448 gfc_char4_t *p4 = (gfc_char4_t *) p;
1449
1450 if (d4 == ' ')
1451 memcpy4 (p4, source, length);
1452 else
1453 {
1454 *p4++ = d4;
1455
1456 for (size_t i = 0; i < length; i++)
1457 {
1458 *p4++ = (gfc_char4_t) source[i];
1459 if (source[i] == d)
1460 *p4++ = d4;
1461 }
1462
1463 *p4 = d4;
1464 }
1465 return;
1466 }
1467
1468 if (d == ' ')
1469 memcpy (p, source, length);
1470 else
1471 {
1472 *p++ = d;
1473
1474 for (size_t i = 0; i < length; i++)
1475 {
1476 *p++ = source[i];
1477 if (source[i] == d)
1478 *p++ = d;
1479 }
1480
1481 *p = d;
1482 }
1483 }
1484 else
1485 {
1486 if (d == ' ')
1487 {
1488 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1489 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1490 else
1491 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1492 }
1493 else
1494 {
1495 p = write_block (dtp, 1);
1496 *p = d;
1497
1498 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1499 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1500 else
1501 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1502
1503 p = write_block (dtp, 1);
1504 *p = d;
1505 }
1506 }
1507 }
1508
1509 /* Floating point helper functions. */
1510
1511 #define BUF_STACK_SZ 384
1512
1513 static int
1514 get_precision (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1515 {
1516 if (f->format != FMT_EN)
1517 return determine_precision (dtp, f, kind);
1518 else
1519 return determine_en_precision (dtp, f, source, kind);
1520 }
1521
1522 /* 4932 is the maximum exponent of long double and quad precision, 3
1523 extra characters for the sign, the decimal point, and the
1524 trailing null. Extra digits are added by the calling functions for
1525 requested precision. Likewise for float and double. F0 editing produces
1526 full precision output. */
1527 static int
1528 size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
1529 {
1530 int size;
1531
1532 if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH)
1533 {
1534 switch (kind)
1535 {
1536 case 4:
1537 size = 38 + 3; /* These constants shown for clarity. */
1538 break;
1539 case 8:
1540 size = 308 + 3;
1541 break;
1542 case 10:
1543 size = 4932 + 3;
1544 break;
1545 case 16:
1546 size = 4932 + 3;
1547 break;
1548 default:
1549 internal_error (&dtp->common, "bad real kind");
1550 break;
1551 }
1552 }
1553 else
1554 size = f->u.real.w + 1; /* One byte for a NULL character. */
1555
1556 return size;
1557 }
1558
1559 static char *
1560 select_buffer (st_parameter_dt *dtp, const fnode *f, int precision,
1561 char *buf, size_t *size, int kind)
1562 {
1563 char *result;
1564
1565 /* The buffer needs at least one more byte to allow room for
1566 normalizing and 1 to hold null terminator. */
1567 *size = size_from_kind (dtp, f, kind) + precision + 1 + 1;
1568
1569 if (*size > BUF_STACK_SZ)
1570 result = xmalloc (*size);
1571 else
1572 result = buf;
1573 return result;
1574 }
1575
1576 static char *
1577 select_string (st_parameter_dt *dtp, const fnode *f, char *buf, size_t *size,
1578 int kind)
1579 {
1580 char *result;
1581 *size = size_from_kind (dtp, f, kind) + f->u.real.d + 1;
1582 if (*size > BUF_STACK_SZ)
1583 result = xmalloc (*size);
1584 else
1585 result = buf;
1586 return result;
1587 }
1588
1589 static void
1590 write_float_string (st_parameter_dt *dtp, char *fstr, size_t len)
1591 {
1592 char *p = write_block (dtp, len);
1593 if (p == NULL)
1594 return;
1595
1596 if (unlikely (is_char4_unit (dtp)))
1597 {
1598 gfc_char4_t *p4 = (gfc_char4_t *) p;
1599 memcpy4 (p4, fstr, len);
1600 return;
1601 }
1602 memcpy (p, fstr, len);
1603 }
1604
1605
1606 static void
1607 write_float_0 (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
1608 {
1609 char buf_stack[BUF_STACK_SZ];
1610 char str_buf[BUF_STACK_SZ];
1611 char *buffer, *result;
1612 size_t buf_size, res_len, flt_str_len;
1613
1614 /* Precision for snprintf call. */
1615 int precision = get_precision (dtp, f, source, kind);
1616
1617 /* String buffer to hold final result. */
1618 result = select_string (dtp, f, str_buf, &res_len, kind);
1619
1620 buffer = select_buffer (dtp, f, precision, buf_stack, &buf_size, kind);
1621
1622 get_float_string (dtp, f, source , kind, 0, buffer,
1623 precision, buf_size, result, &flt_str_len);
1624 write_float_string (dtp, result, flt_str_len);
1625
1626 if (buf_size > BUF_STACK_SZ)
1627 free (buffer);
1628 if (res_len > BUF_STACK_SZ)
1629 free (result);
1630 }
1631
1632 void
1633 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1634 {
1635 write_float_0 (dtp, f, p, len);
1636 }
1637
1638
1639 void
1640 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1641 {
1642 write_float_0 (dtp, f, p, len);
1643 }
1644
1645
1646 void
1647 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1648 {
1649 write_float_0 (dtp, f, p, len);
1650 }
1651
1652
1653 void
1654 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1655 {
1656 write_float_0 (dtp, f, p, len);
1657 }
1658
1659
1660 void
1661 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1662 {
1663 write_float_0 (dtp, f, p, len);
1664 }
1665
1666
1667 /* Set an fnode to default format. */
1668
1669 static void
1670 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
1671 {
1672 f->format = FMT_G;
1673 switch (length)
1674 {
1675 case 4:
1676 f->u.real.w = 16;
1677 f->u.real.d = 9;
1678 f->u.real.e = 2;
1679 break;
1680 case 8:
1681 f->u.real.w = 25;
1682 f->u.real.d = 17;
1683 f->u.real.e = 3;
1684 break;
1685 case 10:
1686 f->u.real.w = 30;
1687 f->u.real.d = 21;
1688 f->u.real.e = 4;
1689 break;
1690 case 16:
1691 /* Adjust decimal precision depending on binary precision, 106 or 113. */
1692 #if GFC_REAL_16_DIGITS == 113
1693 f->u.real.w = 45;
1694 f->u.real.d = 36;
1695 f->u.real.e = 4;
1696 #else
1697 f->u.real.w = 41;
1698 f->u.real.d = 32;
1699 f->u.real.e = 4;
1700 #endif
1701 break;
1702 default:
1703 internal_error (&dtp->common, "bad real kind");
1704 break;
1705 }
1706 }
1707
1708 /* Output a real number with default format.
1709 To guarantee that a binary -> decimal -> binary roundtrip conversion
1710 recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
1711 significant digits for REAL kinds 4, 8, 10, and 16, respectively.
1712 Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
1713 for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
1714 Fortran standard requires outputting an extra digit when the scale
1715 factor is 1 and when the magnitude of the value is such that E
1716 editing is used. However, gfortran compensates for this, and thus
1717 for list formatted the same number of significant digits is
1718 generated both when using F and E editing. */
1719
1720 void
1721 write_real (st_parameter_dt *dtp, const char *source, int kind)
1722 {
1723 fnode f ;
1724 char buf_stack[BUF_STACK_SZ];
1725 char str_buf[BUF_STACK_SZ];
1726 char *buffer, *result;
1727 size_t buf_size, res_len, flt_str_len;
1728 int orig_scale = dtp->u.p.scale_factor;
1729 dtp->u.p.scale_factor = 1;
1730 set_fnode_default (dtp, &f, kind);
1731
1732 /* Precision for snprintf call. */
1733 int precision = get_precision (dtp, &f, source, kind);
1734
1735 /* String buffer to hold final result. */
1736 result = select_string (dtp, &f, str_buf, &res_len, kind);
1737
1738 /* Scratch buffer to hold final result. */
1739 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
1740
1741 get_float_string (dtp, &f, source , kind, 1, buffer,
1742 precision, buf_size, result, &flt_str_len);
1743 write_float_string (dtp, result, flt_str_len);
1744
1745 dtp->u.p.scale_factor = orig_scale;
1746 if (buf_size > BUF_STACK_SZ)
1747 free (buffer);
1748 if (res_len > BUF_STACK_SZ)
1749 free (result);
1750 }
1751
1752 /* Similar to list formatted REAL output, for kPG0 where k > 0 we
1753 compensate for the extra digit. */
1754
1755 void
1756 write_real_w0 (st_parameter_dt *dtp, const char *source, int kind,
1757 const fnode* f)
1758 {
1759 fnode ff;
1760 char buf_stack[BUF_STACK_SZ];
1761 char str_buf[BUF_STACK_SZ];
1762 char *buffer, *result;
1763 size_t buf_size, res_len, flt_str_len;
1764 int comp_d = 0;
1765
1766 set_fnode_default (dtp, &ff, kind);
1767
1768 if (f->u.real.d > 0)
1769 ff.u.real.d = f->u.real.d;
1770 ff.format = f->format;
1771
1772 /* For FMT_G, Compensate for extra digits when using scale factor, d
1773 is not specified, and the magnitude is such that E editing
1774 is used. */
1775 if (f->format == FMT_G)
1776 {
1777 if (dtp->u.p.scale_factor > 0 && f->u.real.d == 0)
1778 comp_d = 1;
1779 else
1780 comp_d = 0;
1781 }
1782
1783 if (f->u.real.e >= 0)
1784 ff.u.real.e = f->u.real.e;
1785
1786 dtp->u.p.g0_no_blanks = 1;
1787
1788 /* Precision for snprintf call. */
1789 int precision = get_precision (dtp, &ff, source, kind);
1790
1791 /* String buffer to hold final result. */
1792 result = select_string (dtp, &ff, str_buf, &res_len, kind);
1793
1794 buffer = select_buffer (dtp, &ff, precision, buf_stack, &buf_size, kind);
1795
1796 get_float_string (dtp, &ff, source , kind, comp_d, buffer,
1797 precision, buf_size, result, &flt_str_len);
1798 write_float_string (dtp, result, flt_str_len);
1799
1800 dtp->u.p.g0_no_blanks = 0;
1801 if (buf_size > BUF_STACK_SZ)
1802 free (buffer);
1803 if (res_len > BUF_STACK_SZ)
1804 free (result);
1805 }
1806
1807
1808 static void
1809 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1810 {
1811 char semi_comma =
1812 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1813
1814 /* Set for no blanks so we get a string result with no leading
1815 blanks. We will pad left later. */
1816 dtp->u.p.g0_no_blanks = 1;
1817
1818 fnode f ;
1819 char buf_stack[BUF_STACK_SZ];
1820 char str1_buf[BUF_STACK_SZ];
1821 char str2_buf[BUF_STACK_SZ];
1822 char *buffer, *result1, *result2;
1823 size_t buf_size, res_len1, res_len2, flt_str_len1, flt_str_len2;
1824 int width, lblanks, orig_scale = dtp->u.p.scale_factor;
1825
1826 dtp->u.p.scale_factor = 1;
1827 set_fnode_default (dtp, &f, kind);
1828
1829 /* Set width for two values, parenthesis, and comma. */
1830 width = 2 * f.u.real.w + 3;
1831
1832 /* Set for no blanks so we get a string result with no leading
1833 blanks. We will pad left later. */
1834 dtp->u.p.g0_no_blanks = 1;
1835
1836 /* Precision for snprintf call. */
1837 int precision = get_precision (dtp, &f, source, kind);
1838
1839 /* String buffers to hold final result. */
1840 result1 = select_string (dtp, &f, str1_buf, &res_len1, kind);
1841 result2 = select_string (dtp, &f, str2_buf, &res_len2, kind);
1842
1843 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
1844
1845 get_float_string (dtp, &f, source , kind, 0, buffer,
1846 precision, buf_size, result1, &flt_str_len1);
1847 get_float_string (dtp, &f, source + size / 2 , kind, 0, buffer,
1848 precision, buf_size, result2, &flt_str_len2);
1849 if (!dtp->u.p.namelist_mode)
1850 {
1851 lblanks = width - flt_str_len1 - flt_str_len2 - 3;
1852 write_x (dtp, lblanks, lblanks);
1853 }
1854 write_char (dtp, '(');
1855 write_float_string (dtp, result1, flt_str_len1);
1856 write_char (dtp, semi_comma);
1857 write_float_string (dtp, result2, flt_str_len2);
1858 write_char (dtp, ')');
1859
1860 dtp->u.p.scale_factor = orig_scale;
1861 dtp->u.p.g0_no_blanks = 0;
1862 if (buf_size > BUF_STACK_SZ)
1863 free (buffer);
1864 if (res_len1 > BUF_STACK_SZ)
1865 free (result1);
1866 if (res_len2 > BUF_STACK_SZ)
1867 free (result2);
1868 }
1869
1870
1871 /* Write the separator between items. */
1872
1873 static void
1874 write_separator (st_parameter_dt *dtp)
1875 {
1876 char *p;
1877
1878 p = write_block (dtp, options.separator_len);
1879 if (p == NULL)
1880 return;
1881 if (unlikely (is_char4_unit (dtp)))
1882 {
1883 gfc_char4_t *p4 = (gfc_char4_t *) p;
1884 memcpy4 (p4, options.separator, options.separator_len);
1885 }
1886 else
1887 memcpy (p, options.separator, options.separator_len);
1888 }
1889
1890
1891 /* Write an item with list formatting.
1892 TODO: handle skipping to the next record correctly, particularly
1893 with strings. */
1894
1895 static void
1896 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1897 size_t size)
1898 {
1899 if (dtp->u.p.current_unit == NULL)
1900 return;
1901
1902 if (dtp->u.p.first_item)
1903 {
1904 dtp->u.p.first_item = 0;
1905 if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
1906 write_char (dtp, ' ');
1907 }
1908 else
1909 {
1910 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1911 (dtp->u.p.current_unit->delim_status != DELIM_NONE
1912 && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
1913 write_separator (dtp);
1914 }
1915
1916 switch (type)
1917 {
1918 case BT_INTEGER:
1919 write_integer (dtp, p, kind);
1920 break;
1921 case BT_LOGICAL:
1922 write_logical (dtp, p, kind);
1923 break;
1924 case BT_CHARACTER:
1925 write_character (dtp, p, kind, size, DELIM);
1926 break;
1927 case BT_REAL:
1928 write_real (dtp, p, kind);
1929 break;
1930 case BT_COMPLEX:
1931 write_complex (dtp, p, kind, size);
1932 break;
1933 case BT_CLASS:
1934 {
1935 int unit = dtp->u.p.current_unit->unit_number;
1936 char iotype[] = "LISTDIRECTED";
1937 gfc_charlen_type iotype_len = 12;
1938 char tmp_iomsg[IOMSG_LEN] = "";
1939 char *child_iomsg;
1940 gfc_charlen_type child_iomsg_len;
1941 int noiostat;
1942 int *child_iostat = NULL;
1943 gfc_full_array_i4 vlist;
1944
1945 GFC_DESCRIPTOR_DATA(&vlist) = NULL;
1946 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
1947
1948 /* Set iostat, intent(out). */
1949 noiostat = 0;
1950 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1951 dtp->common.iostat : &noiostat;
1952
1953 /* Set iomsge, intent(inout). */
1954 if (dtp->common.flags & IOPARM_HAS_IOMSG)
1955 {
1956 child_iomsg = dtp->common.iomsg;
1957 child_iomsg_len = dtp->common.iomsg_len;
1958 }
1959 else
1960 {
1961 child_iomsg = tmp_iomsg;
1962 child_iomsg_len = IOMSG_LEN;
1963 }
1964
1965 /* Call the user defined formatted WRITE procedure. */
1966 dtp->u.p.current_unit->child_dtio++;
1967 dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
1968 child_iostat, child_iomsg,
1969 iotype_len, child_iomsg_len);
1970 dtp->u.p.current_unit->child_dtio--;
1971 }
1972 break;
1973 default:
1974 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1975 }
1976
1977 fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
1978 dtp->u.p.char_flag = (type == BT_CHARACTER);
1979 }
1980
1981
1982 void
1983 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1984 size_t size, size_t nelems)
1985 {
1986 size_t elem;
1987 char *tmp;
1988 size_t stride = type == BT_CHARACTER ?
1989 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1990
1991 tmp = (char *) p;
1992
1993 /* Big loop over all the elements. */
1994 for (elem = 0; elem < nelems; elem++)
1995 {
1996 dtp->u.p.item_count++;
1997 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
1998 }
1999 }
2000
2001 /* NAMELIST OUTPUT
2002
2003 nml_write_obj writes a namelist object to the output stream. It is called
2004 recursively for derived type components:
2005 obj = is the namelist_info for the current object.
2006 offset = the offset relative to the address held by the object for
2007 derived type arrays.
2008 base = is the namelist_info of the derived type, when obj is a
2009 component.
2010 base_name = the full name for a derived type, including qualifiers
2011 if any.
2012 The returned value is a pointer to the object beyond the last one
2013 accessed, including nested derived types. Notice that the namelist is
2014 a linear linked list of objects, including derived types and their
2015 components. A tree, of sorts, is implied by the compound names of
2016 the derived type components and this is how this function recurses through
2017 the list. */
2018
2019 /* A generous estimate of the number of characters needed to print
2020 repeat counts and indices, including commas, asterices and brackets. */
2021
2022 #define NML_DIGITS 20
2023
2024 static void
2025 namelist_write_newline (st_parameter_dt *dtp)
2026 {
2027 if (!is_internal_unit (dtp))
2028 {
2029 #ifdef HAVE_CRLF
2030 write_character (dtp, "\r\n", 1, 2, NODELIM);
2031 #else
2032 write_character (dtp, "\n", 1, 1, NODELIM);
2033 #endif
2034 return;
2035 }
2036
2037 if (is_array_io (dtp))
2038 {
2039 gfc_offset record;
2040 int finished;
2041 char *p;
2042 int length = dtp->u.p.current_unit->bytes_left;
2043
2044 p = write_block (dtp, length);
2045 if (p == NULL)
2046 return;
2047
2048 if (unlikely (is_char4_unit (dtp)))
2049 {
2050 gfc_char4_t *p4 = (gfc_char4_t *) p;
2051 memset4 (p4, ' ', length);
2052 }
2053 else
2054 memset (p, ' ', length);
2055
2056 /* Now that the current record has been padded out,
2057 determine where the next record in the array is. */
2058 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
2059 &finished);
2060 if (finished)
2061 dtp->u.p.current_unit->endfile = AT_ENDFILE;
2062 else
2063 {
2064 /* Now seek to this record */
2065 record = record * dtp->u.p.current_unit->recl;
2066
2067 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
2068 {
2069 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
2070 return;
2071 }
2072
2073 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2074 }
2075 }
2076 else
2077 write_character (dtp, " ", 1, 1, NODELIM);
2078 }
2079
2080
2081 static namelist_info *
2082 nml_write_obj (st_parameter_dt *dtp, namelist_info *obj, index_type offset,
2083 namelist_info *base, char *base_name)
2084 {
2085 int rep_ctr;
2086 int num;
2087 int nml_carry;
2088 int len;
2089 index_type obj_size;
2090 index_type nelem;
2091 size_t dim_i;
2092 size_t clen;
2093 index_type elem_ctr;
2094 size_t obj_name_len;
2095 void *p;
2096 char cup;
2097 char *obj_name;
2098 char *ext_name;
2099 char *q;
2100 size_t ext_name_len;
2101 char rep_buff[NML_DIGITS];
2102 namelist_info *cmp;
2103 namelist_info *retval = obj->next;
2104 size_t base_name_len;
2105 size_t base_var_name_len;
2106 size_t tot_len;
2107
2108 /* Set the character to be used to separate values
2109 to a comma or semi-colon. */
2110
2111 char semi_comma =
2112 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
2113
2114 /* Write namelist variable names in upper case. If a derived type,
2115 nothing is output. If a component, base and base_name are set. */
2116
2117 if (obj->type != BT_DERIVED || obj->dtio_sub != NULL)
2118 {
2119 namelist_write_newline (dtp);
2120 write_character (dtp, " ", 1, 1, NODELIM);
2121
2122 len = 0;
2123 if (base)
2124 {
2125 len = strlen (base->var_name);
2126 base_name_len = strlen (base_name);
2127 for (dim_i = 0; dim_i < base_name_len; dim_i++)
2128 {
2129 cup = safe_toupper (base_name[dim_i]);
2130 write_character (dtp, &cup, 1, 1, NODELIM);
2131 }
2132 }
2133 clen = strlen (obj->var_name);
2134 for (dim_i = len; dim_i < clen; dim_i++)
2135 {
2136 cup = safe_toupper (obj->var_name[dim_i]);
2137 if (cup == '+')
2138 cup = '%';
2139 write_character (dtp, &cup, 1, 1, NODELIM);
2140 }
2141 write_character (dtp, "=", 1, 1, NODELIM);
2142 }
2143
2144 /* Counts the number of data output on a line, including names. */
2145
2146 num = 1;
2147
2148 len = obj->len;
2149
2150 switch (obj->type)
2151 {
2152
2153 case BT_REAL:
2154 obj_size = size_from_real_kind (len);
2155 break;
2156
2157 case BT_COMPLEX:
2158 obj_size = size_from_complex_kind (len);
2159 break;
2160
2161 case BT_CHARACTER:
2162 obj_size = obj->string_length;
2163 break;
2164
2165 default:
2166 obj_size = len;
2167 }
2168
2169 if (obj->var_rank)
2170 obj_size = obj->size;
2171
2172 /* Set the index vector and count the number of elements. */
2173
2174 nelem = 1;
2175 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
2176 {
2177 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
2178 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
2179 }
2180
2181 /* Main loop to output the data held in the object. */
2182
2183 rep_ctr = 1;
2184 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
2185 {
2186
2187 /* Build the pointer to the data value. The offset is passed by
2188 recursive calls to this function for arrays of derived types.
2189 Is NULL otherwise. */
2190
2191 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
2192 p += offset;
2193
2194 /* Check for repeat counts of intrinsic types. */
2195
2196 if ((elem_ctr < (nelem - 1)) &&
2197 (obj->type != BT_DERIVED) &&
2198 !memcmp (p, (void *)(p + obj_size ), obj_size ))
2199 {
2200 rep_ctr++;
2201 }
2202
2203 /* Execute a repeated output. Note the flag no_leading_blank that
2204 is used in the functions used to output the intrinsic types. */
2205
2206 else
2207 {
2208 if (rep_ctr > 1)
2209 {
2210 snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
2211 write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
2212 dtp->u.p.no_leading_blank = 1;
2213 }
2214 num++;
2215
2216 /* Output the data, if an intrinsic type, or recurse into this
2217 routine to treat derived types. */
2218
2219 switch (obj->type)
2220 {
2221
2222 case BT_INTEGER:
2223 write_integer (dtp, p, len);
2224 break;
2225
2226 case BT_LOGICAL:
2227 write_logical (dtp, p, len);
2228 break;
2229
2230 case BT_CHARACTER:
2231 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
2232 write_character (dtp, p, 4, obj->string_length, DELIM);
2233 else
2234 write_character (dtp, p, 1, obj->string_length, DELIM);
2235 break;
2236
2237 case BT_REAL:
2238 write_real (dtp, p, len);
2239 break;
2240
2241 case BT_COMPLEX:
2242 dtp->u.p.no_leading_blank = 0;
2243 num++;
2244 write_complex (dtp, p, len, obj_size);
2245 break;
2246
2247 case BT_DERIVED:
2248 case BT_CLASS:
2249 /* To treat a derived type, we need to build two strings:
2250 ext_name = the name, including qualifiers that prepends
2251 component names in the output - passed to
2252 nml_write_obj.
2253 obj_name = the derived type name with no qualifiers but %
2254 appended. This is used to identify the
2255 components. */
2256
2257 /* First ext_name => get length of all possible components */
2258 if (obj->dtio_sub != NULL)
2259 {
2260 int unit = dtp->u.p.current_unit->unit_number;
2261 char iotype[] = "NAMELIST";
2262 gfc_charlen_type iotype_len = 8;
2263 char tmp_iomsg[IOMSG_LEN] = "";
2264 char *child_iomsg;
2265 gfc_charlen_type child_iomsg_len;
2266 int noiostat;
2267 int *child_iostat = NULL;
2268 gfc_full_array_i4 vlist;
2269 formatted_dtio dtio_ptr = (formatted_dtio)obj->dtio_sub;
2270
2271 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
2272
2273 /* Set iostat, intent(out). */
2274 noiostat = 0;
2275 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
2276 dtp->common.iostat : &noiostat;
2277
2278 /* Set iomsg, intent(inout). */
2279 if (dtp->common.flags & IOPARM_HAS_IOMSG)
2280 {
2281 child_iomsg = dtp->common.iomsg;
2282 child_iomsg_len = dtp->common.iomsg_len;
2283 }
2284 else
2285 {
2286 child_iomsg = tmp_iomsg;
2287 child_iomsg_len = IOMSG_LEN;
2288 }
2289
2290 /* Call the user defined formatted WRITE procedure. */
2291 dtp->u.p.current_unit->child_dtio++;
2292 if (obj->type == BT_DERIVED)
2293 {
2294 /* Build a class container. */
2295 gfc_class list_obj;
2296 list_obj.data = p;
2297 list_obj.vptr = obj->vtable;
2298 list_obj.len = 0;
2299 dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
2300 child_iostat, child_iomsg,
2301 iotype_len, child_iomsg_len);
2302 }
2303 else
2304 {
2305 dtio_ptr (p, &unit, iotype, &vlist,
2306 child_iostat, child_iomsg,
2307 iotype_len, child_iomsg_len);
2308 }
2309 dtp->u.p.current_unit->child_dtio--;
2310
2311 goto obj_loop;
2312 }
2313
2314 base_name_len = base_name ? strlen (base_name) : 0;
2315 base_var_name_len = base ? strlen (base->var_name) : 0;
2316 ext_name_len = base_name_len + base_var_name_len
2317 + strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
2318 ext_name = xmalloc (ext_name_len);
2319
2320 if (base_name)
2321 memcpy (ext_name, base_name, base_name_len);
2322 clen = strlen (obj->var_name + base_var_name_len);
2323 memcpy (ext_name + base_name_len,
2324 obj->var_name + base_var_name_len, clen);
2325
2326 /* Append the qualifier. */
2327
2328 tot_len = base_name_len + clen;
2329 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
2330 {
2331 if (!dim_i)
2332 {
2333 ext_name[tot_len] = '(';
2334 tot_len++;
2335 }
2336 snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
2337 (int) obj->ls[dim_i].idx);
2338 tot_len += strlen (ext_name + tot_len);
2339 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
2340 tot_len++;
2341 }
2342
2343 ext_name[tot_len] = '\0';
2344 for (q = ext_name; *q; q++)
2345 if (*q == '+')
2346 *q = '%';
2347
2348 /* Now obj_name. */
2349
2350 obj_name_len = strlen (obj->var_name) + 1;
2351 obj_name = xmalloc (obj_name_len + 1);
2352 memcpy (obj_name, obj->var_name, obj_name_len-1);
2353 memcpy (obj_name + obj_name_len-1, "%", 2);
2354
2355 /* Now loop over the components. Update the component pointer
2356 with the return value from nml_write_obj => this loop jumps
2357 past nested derived types. */
2358
2359 for (cmp = obj->next;
2360 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
2361 cmp = retval)
2362 {
2363 retval = nml_write_obj (dtp, cmp,
2364 (index_type)(p - obj->mem_pos),
2365 obj, ext_name);
2366 }
2367
2368 free (obj_name);
2369 free (ext_name);
2370 goto obj_loop;
2371
2372 default:
2373 internal_error (&dtp->common, "Bad type for namelist write");
2374 }
2375
2376 /* Reset the leading blank suppression, write a comma (or semi-colon)
2377 and, if 5 values have been output, write a newline and advance
2378 to column 2. Reset the repeat counter. */
2379
2380 dtp->u.p.no_leading_blank = 0;
2381 if (obj->type == BT_CHARACTER)
2382 {
2383 if (dtp->u.p.nml_delim != '\0')
2384 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2385 }
2386 else
2387 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2388 if (num > 5)
2389 {
2390 num = 0;
2391 if (dtp->u.p.nml_delim == '\0')
2392 write_character (dtp, &semi_comma, 1, 1, NODELIM);
2393 namelist_write_newline (dtp);
2394 write_character (dtp, " ", 1, 1, NODELIM);
2395 }
2396 rep_ctr = 1;
2397 }
2398
2399 /* Cycle through and increment the index vector. */
2400
2401 obj_loop:
2402
2403 nml_carry = 1;
2404 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
2405 {
2406 obj->ls[dim_i].idx += nml_carry ;
2407 nml_carry = 0;
2408 if (obj->ls[dim_i].idx > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
2409 {
2410 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
2411 nml_carry = 1;
2412 }
2413 }
2414 }
2415
2416 /* Return a pointer beyond the furthest object accessed. */
2417
2418 return retval;
2419 }
2420
2421
2422 /* This is the entry function for namelist writes. It outputs the name
2423 of the namelist and iterates through the namelist by calls to
2424 nml_write_obj. The call below has dummys in the arguments used in
2425 the treatment of derived types. */
2426
2427 void
2428 namelist_write (st_parameter_dt *dtp)
2429 {
2430 namelist_info *t1, *t2, *dummy = NULL;
2431 index_type dummy_offset = 0;
2432 char c;
2433 char *dummy_name = NULL;
2434
2435 /* Set the delimiter for namelist output. */
2436 switch (dtp->u.p.current_unit->delim_status)
2437 {
2438 case DELIM_APOSTROPHE:
2439 dtp->u.p.nml_delim = '\'';
2440 break;
2441 case DELIM_QUOTE:
2442 case DELIM_UNSPECIFIED:
2443 dtp->u.p.nml_delim = '"';
2444 break;
2445 default:
2446 dtp->u.p.nml_delim = '\0';
2447 }
2448
2449 write_character (dtp, "&", 1, 1, NODELIM);
2450
2451 /* Write namelist name in upper case - f95 std. */
2452 for (gfc_charlen_type i = 0; i < dtp->namelist_name_len; i++ )
2453 {
2454 c = safe_toupper (dtp->namelist_name[i]);
2455 write_character (dtp, &c, 1 ,1, NODELIM);
2456 }
2457
2458 if (dtp->u.p.ionml != NULL)
2459 {
2460 t1 = dtp->u.p.ionml;
2461 while (t1 != NULL)
2462 {
2463 t2 = t1;
2464 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
2465 }
2466 }
2467
2468 namelist_write_newline (dtp);
2469 write_character (dtp, " /", 1, 2, NODELIM);
2470 }
2471
2472 #undef NML_DIGITS