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