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