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