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