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