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