]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/io/write.c
Remove free_mem
[thirdparty/gcc.git] / libgfortran / io / write.c
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 Namelist output contributed by Paul Thomas
5 F2003 I/O support contributed by Jerry DeLisle
6
7 This file is part of the GNU Fortran runtime library (libgfortran).
8
9 Libgfortran is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 Libgfortran is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
22
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
27
28 #include "io.h"
29 #include "format.h"
30 #include "unix.h"
31 #include <assert.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <stdlib.h>
35 #include <stdbool.h>
36 #include <errno.h>
37 #define star_fill(p, n) memset(p, '*', n)
38
39 #include "write_float.def"
40
41 typedef unsigned char uchar;
42
43 /* Write out default char4. */
44
45 static void
46 write_default_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
47 int src_len, int w_len)
48 {
49 char *p;
50 int j, k = 0;
51 gfc_char4_t c;
52 uchar d;
53
54 /* Take care of preceding blanks. */
55 if (w_len > src_len)
56 {
57 k = w_len - src_len;
58 p = write_block (dtp, k);
59 if (p == NULL)
60 return;
61 memset (p, ' ', k);
62 }
63
64 /* Get ready to handle delimiters if needed. */
65 switch (dtp->u.p.current_unit->delim_status)
66 {
67 case DELIM_APOSTROPHE:
68 d = '\'';
69 break;
70 case DELIM_QUOTE:
71 d = '"';
72 break;
73 default:
74 d = ' ';
75 break;
76 }
77
78 /* Now process the remaining characters, one at a time. */
79 for (j = k; j < src_len; j++)
80 {
81 c = source[j];
82
83 /* Handle delimiters if any. */
84 if (c == d && d != ' ')
85 {
86 p = write_block (dtp, 2);
87 if (p == NULL)
88 return;
89 *p++ = (uchar) c;
90 }
91 else
92 {
93 p = write_block (dtp, 1);
94 if (p == NULL)
95 return;
96 }
97 *p = c > 255 ? '?' : (uchar) c;
98 }
99 }
100
101
102 /* Write out UTF-8 converted from char4. */
103
104 static void
105 write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
106 int src_len, int w_len)
107 {
108 char *p;
109 int j, k = 0;
110 gfc_char4_t c;
111 static const uchar masks[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
112 static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
113 int nbytes;
114 uchar buf[6], d, *q;
115
116 /* Take care of preceding blanks. */
117 if (w_len > src_len)
118 {
119 k = w_len - src_len;
120 p = write_block (dtp, k);
121 if (p == NULL)
122 return;
123 memset (p, ' ', k);
124 }
125
126 /* Get ready to handle delimiters if needed. */
127 switch (dtp->u.p.current_unit->delim_status)
128 {
129 case DELIM_APOSTROPHE:
130 d = '\'';
131 break;
132 case DELIM_QUOTE:
133 d = '"';
134 break;
135 default:
136 d = ' ';
137 break;
138 }
139
140 /* Now process the remaining characters, one at a time. */
141 for (j = k; j < src_len; j++)
142 {
143 c = source[j];
144 if (c < 0x80)
145 {
146 /* Handle the delimiters if any. */
147 if (c == d && d != ' ')
148 {
149 p = write_block (dtp, 2);
150 if (p == NULL)
151 return;
152 *p++ = (uchar) c;
153 }
154 else
155 {
156 p = write_block (dtp, 1);
157 if (p == NULL)
158 return;
159 }
160 *p = (uchar) c;
161 }
162 else
163 {
164 /* Convert to UTF-8 sequence. */
165 nbytes = 1;
166 q = &buf[6];
167
168 do
169 {
170 *--q = ((c & 0x3F) | 0x80);
171 c >>= 6;
172 nbytes++;
173 }
174 while (c >= 0x3F || (c & limits[nbytes-1]));
175
176 *--q = (c | masks[nbytes-1]);
177
178 p = write_block (dtp, nbytes);
179 if (p == NULL)
180 return;
181
182 while (q < &buf[6])
183 *p++ = *q++;
184 }
185 }
186 }
187
188
189 void
190 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
191 {
192 int wlen;
193 char *p;
194
195 wlen = f->u.string.length < 0
196 || (f->format == FMT_G && f->u.string.length == 0)
197 ? len : f->u.string.length;
198
199 #ifdef HAVE_CRLF
200 /* If this is formatted STREAM IO convert any embedded line feed characters
201 to CR_LF on systems that use that sequence for newlines. See F2003
202 Standard sections 10.6.3 and 9.9 for further information. */
203 if (is_stream_io (dtp))
204 {
205 const char crlf[] = "\r\n";
206 int i, q, bytes;
207 q = bytes = 0;
208
209 /* Write out any padding if needed. */
210 if (len < wlen)
211 {
212 p = write_block (dtp, wlen - len);
213 if (p == NULL)
214 return;
215 memset (p, ' ', wlen - len);
216 }
217
218 /* Scan the source string looking for '\n' and convert it if found. */
219 for (i = 0; i < wlen; i++)
220 {
221 if (source[i] == '\n')
222 {
223 /* Write out the previously scanned characters in the string. */
224 if (bytes > 0)
225 {
226 p = write_block (dtp, bytes);
227 if (p == NULL)
228 return;
229 memcpy (p, &source[q], bytes);
230 q += bytes;
231 bytes = 0;
232 }
233
234 /* Write out the CR_LF sequence. */
235 q++;
236 p = write_block (dtp, 2);
237 if (p == NULL)
238 return;
239 memcpy (p, crlf, 2);
240 }
241 else
242 bytes++;
243 }
244
245 /* Write out any remaining bytes if no LF was found. */
246 if (bytes > 0)
247 {
248 p = write_block (dtp, bytes);
249 if (p == NULL)
250 return;
251 memcpy (p, &source[q], bytes);
252 }
253 }
254 else
255 {
256 #endif
257 p = write_block (dtp, wlen);
258 if (p == NULL)
259 return;
260
261 if (wlen < len)
262 memcpy (p, source, wlen);
263 else
264 {
265 memset (p, ' ', wlen - len);
266 memcpy (p + wlen - len, source, len);
267 }
268 #ifdef HAVE_CRLF
269 }
270 #endif
271 }
272
273
274 /* The primary difference between write_a_char4 and write_a is that we have to
275 deal with writing from the first byte of the 4-byte character and pay
276 attention to the most significant bytes. For ENCODING="default" write the
277 lowest significant byte. If the 3 most significant bytes contain
278 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
279 to the UTF-8 encoded string before writing out. */
280
281 void
282 write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
283 {
284 int wlen;
285 gfc_char4_t *q;
286
287 wlen = f->u.string.length < 0
288 || (f->format == FMT_G && f->u.string.length == 0)
289 ? len : f->u.string.length;
290
291 q = (gfc_char4_t *) source;
292 #ifdef HAVE_CRLF
293 /* If this is formatted STREAM IO convert any embedded line feed characters
294 to CR_LF on systems that use that sequence for newlines. See F2003
295 Standard sections 10.6.3 and 9.9 for further information. */
296 if (is_stream_io (dtp))
297 {
298 const gfc_char4_t crlf[] = {0x000d,0x000a};
299 int i, bytes;
300 gfc_char4_t *qq;
301 bytes = 0;
302
303 /* Write out any padding if needed. */
304 if (len < wlen)
305 {
306 char *p;
307 p = write_block (dtp, wlen - len);
308 if (p == NULL)
309 return;
310 memset (p, ' ', wlen - len);
311 }
312
313 /* Scan the source string looking for '\n' and convert it if found. */
314 qq = (gfc_char4_t *) source;
315 for (i = 0; i < wlen; i++)
316 {
317 if (qq[i] == '\n')
318 {
319 /* Write out the previously scanned characters in the string. */
320 if (bytes > 0)
321 {
322 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
323 write_utf8_char4 (dtp, q, bytes, 0);
324 else
325 write_default_char4 (dtp, q, bytes, 0);
326 bytes = 0;
327 }
328
329 /* Write out the CR_LF sequence. */
330 write_default_char4 (dtp, crlf, 2, 0);
331 }
332 else
333 bytes++;
334 }
335
336 /* Write out any remaining bytes if no LF was found. */
337 if (bytes > 0)
338 {
339 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
340 write_utf8_char4 (dtp, q, bytes, 0);
341 else
342 write_default_char4 (dtp, q, bytes, 0);
343 }
344 }
345 else
346 {
347 #endif
348 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
349 write_utf8_char4 (dtp, q, len, wlen);
350 else
351 write_default_char4 (dtp, q, len, wlen);
352 #ifdef HAVE_CRLF
353 }
354 #endif
355 }
356
357
358 static GFC_INTEGER_LARGEST
359 extract_int (const void *p, int len)
360 {
361 GFC_INTEGER_LARGEST i = 0;
362
363 if (p == NULL)
364 return i;
365
366 switch (len)
367 {
368 case 1:
369 {
370 GFC_INTEGER_1 tmp;
371 memcpy ((void *) &tmp, p, len);
372 i = tmp;
373 }
374 break;
375 case 2:
376 {
377 GFC_INTEGER_2 tmp;
378 memcpy ((void *) &tmp, p, len);
379 i = tmp;
380 }
381 break;
382 case 4:
383 {
384 GFC_INTEGER_4 tmp;
385 memcpy ((void *) &tmp, p, len);
386 i = tmp;
387 }
388 break;
389 case 8:
390 {
391 GFC_INTEGER_8 tmp;
392 memcpy ((void *) &tmp, p, len);
393 i = tmp;
394 }
395 break;
396 #ifdef HAVE_GFC_INTEGER_16
397 case 16:
398 {
399 GFC_INTEGER_16 tmp;
400 memcpy ((void *) &tmp, p, len);
401 i = tmp;
402 }
403 break;
404 #endif
405 default:
406 internal_error (NULL, "bad integer kind");
407 }
408
409 return i;
410 }
411
412 static GFC_UINTEGER_LARGEST
413 extract_uint (const void *p, int len)
414 {
415 GFC_UINTEGER_LARGEST i = 0;
416
417 if (p == NULL)
418 return i;
419
420 switch (len)
421 {
422 case 1:
423 {
424 GFC_INTEGER_1 tmp;
425 memcpy ((void *) &tmp, p, len);
426 i = (GFC_UINTEGER_1) tmp;
427 }
428 break;
429 case 2:
430 {
431 GFC_INTEGER_2 tmp;
432 memcpy ((void *) &tmp, p, len);
433 i = (GFC_UINTEGER_2) tmp;
434 }
435 break;
436 case 4:
437 {
438 GFC_INTEGER_4 tmp;
439 memcpy ((void *) &tmp, p, len);
440 i = (GFC_UINTEGER_4) tmp;
441 }
442 break;
443 case 8:
444 {
445 GFC_INTEGER_8 tmp;
446 memcpy ((void *) &tmp, p, len);
447 i = (GFC_UINTEGER_8) tmp;
448 }
449 break;
450 #ifdef HAVE_GFC_INTEGER_16
451 case 10:
452 case 16:
453 {
454 GFC_INTEGER_16 tmp = 0;
455 memcpy ((void *) &tmp, p, len);
456 i = (GFC_UINTEGER_16) tmp;
457 }
458 break;
459 #endif
460 default:
461 internal_error (NULL, "bad integer kind");
462 }
463
464 return i;
465 }
466
467
468 void
469 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
470 {
471 char *p;
472 int wlen;
473 GFC_INTEGER_LARGEST n;
474
475 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
476
477 p = write_block (dtp, wlen);
478 if (p == NULL)
479 return;
480
481 memset (p, ' ', wlen - 1);
482 n = extract_int (source, len);
483 p[wlen - 1] = (n) ? 'T' : 'F';
484 }
485
486
487 static void
488 write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
489 {
490 int w, m, digits, nzero, nblank;
491 char *p;
492
493 w = f->u.integer.w;
494 m = f->u.integer.m;
495
496 /* Special case: */
497
498 if (m == 0 && n == 0)
499 {
500 if (w == 0)
501 w = 1;
502
503 p = write_block (dtp, w);
504 if (p == NULL)
505 return;
506
507 memset (p, ' ', w);
508 goto done;
509 }
510
511 digits = strlen (q);
512
513 /* Select a width if none was specified. The idea here is to always
514 print something. */
515
516 if (w == 0)
517 w = ((digits < m) ? m : digits);
518
519 p = write_block (dtp, w);
520 if (p == NULL)
521 return;
522
523 nzero = 0;
524 if (digits < m)
525 nzero = m - digits;
526
527 /* See if things will work. */
528
529 nblank = w - (nzero + digits);
530
531 if (nblank < 0)
532 {
533 star_fill (p, w);
534 goto done;
535 }
536
537 if (!dtp->u.p.no_leading_blank)
538 {
539 memset (p, ' ', nblank);
540 p += nblank;
541 memset (p, '0', nzero);
542 p += nzero;
543 memcpy (p, q, digits);
544 }
545 else
546 {
547 memset (p, '0', nzero);
548 p += nzero;
549 memcpy (p, q, digits);
550 p += digits;
551 memset (p, ' ', nblank);
552 dtp->u.p.no_leading_blank = 0;
553 }
554
555 done:
556 return;
557 }
558
559 static void
560 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
561 int len,
562 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
563 {
564 GFC_INTEGER_LARGEST n = 0;
565 int w, m, digits, nsign, nzero, nblank;
566 char *p;
567 const char *q;
568 sign_t sign;
569 char itoa_buf[GFC_BTOA_BUF_SIZE];
570
571 w = f->u.integer.w;
572 m = f->format == FMT_G ? -1 : f->u.integer.m;
573
574 n = extract_int (source, len);
575
576 /* Special case: */
577 if (m == 0 && n == 0)
578 {
579 if (w == 0)
580 w = 1;
581
582 p = write_block (dtp, w);
583 if (p == NULL)
584 return;
585
586 memset (p, ' ', w);
587 goto done;
588 }
589
590 sign = calculate_sign (dtp, n < 0);
591 if (n < 0)
592 n = -n;
593 nsign = sign == S_NONE ? 0 : 1;
594
595 /* conv calls itoa which sets the negative sign needed
596 by write_integer. The sign '+' or '-' is set below based on sign
597 calculated above, so we just point past the sign in the string
598 before proceeding to avoid double signs in corner cases.
599 (see PR38504) */
600 q = conv (n, itoa_buf, sizeof (itoa_buf));
601 if (*q == '-')
602 q++;
603
604 digits = strlen (q);
605
606 /* Select a width if none was specified. The idea here is to always
607 print something. */
608
609 if (w == 0)
610 w = ((digits < m) ? m : digits) + nsign;
611
612 p = write_block (dtp, w);
613 if (p == NULL)
614 return;
615
616 nzero = 0;
617 if (digits < m)
618 nzero = m - digits;
619
620 /* See if things will work. */
621
622 nblank = w - (nsign + nzero + digits);
623
624 if (nblank < 0)
625 {
626 star_fill (p, w);
627 goto done;
628 }
629
630 memset (p, ' ', nblank);
631 p += nblank;
632
633 switch (sign)
634 {
635 case S_PLUS:
636 *p++ = '+';
637 break;
638 case S_MINUS:
639 *p++ = '-';
640 break;
641 case S_NONE:
642 break;
643 }
644
645 memset (p, '0', nzero);
646 p += nzero;
647
648 memcpy (p, q, digits);
649
650 done:
651 return;
652 }
653
654
655 /* Convert unsigned octal to ascii. */
656
657 static const char *
658 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
659 {
660 char *p;
661
662 assert (len >= GFC_OTOA_BUF_SIZE);
663
664 if (n == 0)
665 return "0";
666
667 p = buffer + GFC_OTOA_BUF_SIZE - 1;
668 *p = '\0';
669
670 while (n != 0)
671 {
672 *--p = '0' + (n & 7);
673 n >>= 3;
674 }
675
676 return p;
677 }
678
679
680 /* Convert unsigned binary to ascii. */
681
682 static const char *
683 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
684 {
685 char *p;
686
687 assert (len >= GFC_BTOA_BUF_SIZE);
688
689 if (n == 0)
690 return "0";
691
692 p = buffer + GFC_BTOA_BUF_SIZE - 1;
693 *p = '\0';
694
695 while (n != 0)
696 {
697 *--p = '0' + (n & 1);
698 n >>= 1;
699 }
700
701 return p;
702 }
703
704 /* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
705 to convert large reals with kind sizes that exceed the largest integer type
706 available on certain platforms. In these cases, byte by byte conversion is
707 performed. Endianess is taken into account. */
708
709 /* Conversion to binary. */
710
711 static const char *
712 btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
713 {
714 char *q;
715 int i, j;
716
717 q = buffer;
718 if (big_endian)
719 {
720 const char *p = s;
721 for (i = 0; i < len; i++)
722 {
723 char c = *p;
724
725 /* Test for zero. Needed by write_boz later. */
726 if (*p != 0)
727 *n = 1;
728
729 for (j = 0; j < 8; j++)
730 {
731 *q++ = (c & 128) ? '1' : '0';
732 c <<= 1;
733 }
734 p++;
735 }
736 }
737 else
738 {
739 const char *p = s + len - 1;
740 for (i = 0; i < len; i++)
741 {
742 char c = *p;
743
744 /* Test for zero. Needed by write_boz later. */
745 if (*p != 0)
746 *n = 1;
747
748 for (j = 0; j < 8; j++)
749 {
750 *q++ = (c & 128) ? '1' : '0';
751 c <<= 1;
752 }
753 p--;
754 }
755 }
756
757 *q = '\0';
758
759 if (*n == 0)
760 return "0";
761
762 /* Move past any leading zeros. */
763 while (*buffer == '0')
764 buffer++;
765
766 return buffer;
767
768 }
769
770 /* Conversion to octal. */
771
772 static const char *
773 otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
774 {
775 char *q;
776 int i, j, k;
777 uint8_t octet;
778
779 q = buffer + GFC_OTOA_BUF_SIZE - 1;
780 *q = '\0';
781 i = k = octet = 0;
782
783 if (big_endian)
784 {
785 const char *p = s + len - 1;
786 char c = *p;
787 while (i < len)
788 {
789 /* Test for zero. Needed by write_boz later. */
790 if (*p != 0)
791 *n = 1;
792
793 for (j = 0; j < 3 && i < len; j++)
794 {
795 octet |= (c & 1) << j;
796 c >>= 1;
797 if (++k > 7)
798 {
799 i++;
800 k = 0;
801 c = *--p;
802 }
803 }
804 *--q = '0' + octet;
805 octet = 0;
806 }
807 }
808 else
809 {
810 const char *p = s;
811 char c = *p;
812 while (i < len)
813 {
814 /* Test for zero. Needed by write_boz later. */
815 if (*p != 0)
816 *n = 1;
817
818 for (j = 0; j < 3 && i < len; j++)
819 {
820 octet |= (c & 1) << j;
821 c >>= 1;
822 if (++k > 7)
823 {
824 i++;
825 k = 0;
826 c = *++p;
827 }
828 }
829 *--q = '0' + octet;
830 octet = 0;
831 }
832 }
833
834 if (*n == 0)
835 return "0";
836
837 /* Move past any leading zeros. */
838 while (*q == '0')
839 q++;
840
841 return q;
842 }
843
844 /* Conversion to hexidecimal. */
845
846 static const char *
847 ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
848 {
849 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
850 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
851
852 char *q;
853 uint8_t h, l;
854 int i;
855
856 q = buffer;
857
858 if (big_endian)
859 {
860 const char *p = s;
861 for (i = 0; i < len; i++)
862 {
863 /* Test for zero. Needed by write_boz later. */
864 if (*p != 0)
865 *n = 1;
866
867 h = (*p >> 4) & 0x0F;
868 l = *p++ & 0x0F;
869 *q++ = a[h];
870 *q++ = a[l];
871 }
872 }
873 else
874 {
875 const char *p = s + len - 1;
876 for (i = 0; i < len; i++)
877 {
878 /* Test for zero. Needed by write_boz later. */
879 if (*p != 0)
880 *n = 1;
881
882 h = (*p >> 4) & 0x0F;
883 l = *p-- & 0x0F;
884 *q++ = a[h];
885 *q++ = a[l];
886 }
887 }
888
889 *q = '\0';
890
891 if (*n == 0)
892 return "0";
893
894 /* Move past any leading zeros. */
895 while (*buffer == '0')
896 buffer++;
897
898 return buffer;
899 }
900
901 /* gfc_itoa()-- Integer to decimal conversion.
902 The itoa function is a widespread non-standard extension to standard
903 C, often declared in <stdlib.h>. Even though the itoa defined here
904 is a static function we take care not to conflict with any prior
905 non-static declaration. Hence the 'gfc_' prefix, which is normally
906 reserved for functions with external linkage. */
907
908 static const char *
909 gfc_itoa (GFC_INTEGER_LARGEST n, char *buffer, size_t len)
910 {
911 int negative;
912 char *p;
913 GFC_UINTEGER_LARGEST t;
914
915 assert (len >= GFC_ITOA_BUF_SIZE);
916
917 if (n == 0)
918 return "0";
919
920 negative = 0;
921 t = n;
922 if (n < 0)
923 {
924 negative = 1;
925 t = -n; /*must use unsigned to protect from overflow*/
926 }
927
928 p = buffer + GFC_ITOA_BUF_SIZE - 1;
929 *p = '\0';
930
931 while (t != 0)
932 {
933 *--p = '0' + (t % 10);
934 t /= 10;
935 }
936
937 if (negative)
938 *--p = '-';
939 return p;
940 }
941
942
943 void
944 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
945 {
946 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
947 }
948
949
950 void
951 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
952 {
953 const char *p;
954 char itoa_buf[GFC_BTOA_BUF_SIZE];
955 GFC_UINTEGER_LARGEST n = 0;
956
957 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
958 {
959 p = btoa_big (source, itoa_buf, len, &n);
960 write_boz (dtp, f, p, n);
961 }
962 else
963 {
964 n = extract_uint (source, len);
965 p = btoa (n, itoa_buf, sizeof (itoa_buf));
966 write_boz (dtp, f, p, n);
967 }
968 }
969
970
971 void
972 write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
973 {
974 const char *p;
975 char itoa_buf[GFC_OTOA_BUF_SIZE];
976 GFC_UINTEGER_LARGEST n = 0;
977
978 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
979 {
980 p = otoa_big (source, itoa_buf, len, &n);
981 write_boz (dtp, f, p, n);
982 }
983 else
984 {
985 n = extract_uint (source, len);
986 p = otoa (n, itoa_buf, sizeof (itoa_buf));
987 write_boz (dtp, f, p, n);
988 }
989 }
990
991 void
992 write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
993 {
994 const char *p;
995 char itoa_buf[GFC_XTOA_BUF_SIZE];
996 GFC_UINTEGER_LARGEST n = 0;
997
998 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
999 {
1000 p = ztoa_big (source, itoa_buf, len, &n);
1001 write_boz (dtp, f, p, n);
1002 }
1003 else
1004 {
1005 n = extract_uint (source, len);
1006 p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
1007 write_boz (dtp, f, p, n);
1008 }
1009 }
1010
1011
1012 void
1013 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1014 {
1015 write_float (dtp, f, p, len);
1016 }
1017
1018
1019 void
1020 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1021 {
1022 write_float (dtp, f, p, len);
1023 }
1024
1025
1026 void
1027 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1028 {
1029 write_float (dtp, f, p, len);
1030 }
1031
1032
1033 void
1034 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1035 {
1036 write_float (dtp, f, p, len);
1037 }
1038
1039
1040 void
1041 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
1042 {
1043 write_float (dtp, f, p, len);
1044 }
1045
1046
1047 /* Take care of the X/TR descriptor. */
1048
1049 void
1050 write_x (st_parameter_dt *dtp, int len, int nspaces)
1051 {
1052 char *p;
1053
1054 p = write_block (dtp, len);
1055 if (p == NULL)
1056 return;
1057 if (nspaces > 0 && len - nspaces >= 0)
1058 memset (&p[len - nspaces], ' ', nspaces);
1059 }
1060
1061
1062 /* List-directed writing. */
1063
1064
1065 /* Write a single character to the output. Returns nonzero if
1066 something goes wrong. */
1067
1068 static int
1069 write_char (st_parameter_dt *dtp, char c)
1070 {
1071 char *p;
1072
1073 p = write_block (dtp, 1);
1074 if (p == NULL)
1075 return 1;
1076
1077 *p = c;
1078
1079 return 0;
1080 }
1081
1082
1083 /* Write a list-directed logical value. */
1084
1085 static void
1086 write_logical (st_parameter_dt *dtp, const char *source, int length)
1087 {
1088 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
1089 }
1090
1091
1092 /* Write a list-directed integer value. */
1093
1094 static void
1095 write_integer (st_parameter_dt *dtp, const char *source, int length)
1096 {
1097 char *p;
1098 const char *q;
1099 int digits;
1100 int width;
1101 char itoa_buf[GFC_ITOA_BUF_SIZE];
1102
1103 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
1104
1105 switch (length)
1106 {
1107 case 1:
1108 width = 4;
1109 break;
1110
1111 case 2:
1112 width = 6;
1113 break;
1114
1115 case 4:
1116 width = 11;
1117 break;
1118
1119 case 8:
1120 width = 20;
1121 break;
1122
1123 default:
1124 width = 0;
1125 break;
1126 }
1127
1128 digits = strlen (q);
1129
1130 if (width < digits)
1131 width = digits;
1132 p = write_block (dtp, width);
1133 if (p == NULL)
1134 return;
1135 if (dtp->u.p.no_leading_blank)
1136 {
1137 memcpy (p, q, digits);
1138 memset (p + digits, ' ', width - digits);
1139 }
1140 else
1141 {
1142 memset (p, ' ', width - digits);
1143 memcpy (p + width - digits, q, digits);
1144 }
1145 }
1146
1147
1148 /* Write a list-directed string. We have to worry about delimiting
1149 the strings if the file has been opened in that mode. */
1150
1151 static void
1152 write_character (st_parameter_dt *dtp, const char *source, int kind, int length)
1153 {
1154 int i, extra;
1155 char *p, d;
1156
1157 switch (dtp->u.p.current_unit->delim_status)
1158 {
1159 case DELIM_APOSTROPHE:
1160 d = '\'';
1161 break;
1162 case DELIM_QUOTE:
1163 d = '"';
1164 break;
1165 default:
1166 d = ' ';
1167 break;
1168 }
1169
1170 if (kind == 1)
1171 {
1172 if (d == ' ')
1173 extra = 0;
1174 else
1175 {
1176 extra = 2;
1177
1178 for (i = 0; i < length; i++)
1179 if (source[i] == d)
1180 extra++;
1181 }
1182
1183 p = write_block (dtp, length + extra);
1184 if (p == NULL)
1185 return;
1186
1187 if (d == ' ')
1188 memcpy (p, source, length);
1189 else
1190 {
1191 *p++ = d;
1192
1193 for (i = 0; i < length; i++)
1194 {
1195 *p++ = source[i];
1196 if (source[i] == d)
1197 *p++ = d;
1198 }
1199
1200 *p = d;
1201 }
1202 }
1203 else
1204 {
1205 if (d == ' ')
1206 {
1207 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1208 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1209 else
1210 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1211 }
1212 else
1213 {
1214 p = write_block (dtp, 1);
1215 *p = d;
1216
1217 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
1218 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
1219 else
1220 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
1221
1222 p = write_block (dtp, 1);
1223 *p = d;
1224 }
1225 }
1226 }
1227
1228
1229 /* Set an fnode to default format. */
1230
1231 static void
1232 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
1233 {
1234 f->format = FMT_G;
1235 switch (length)
1236 {
1237 case 4:
1238 f->u.real.w = 15;
1239 f->u.real.d = 8;
1240 f->u.real.e = 2;
1241 break;
1242 case 8:
1243 f->u.real.w = 25;
1244 f->u.real.d = 17;
1245 f->u.real.e = 3;
1246 break;
1247 case 10:
1248 f->u.real.w = 29;
1249 f->u.real.d = 20;
1250 f->u.real.e = 4;
1251 break;
1252 case 16:
1253 f->u.real.w = 44;
1254 f->u.real.d = 35;
1255 f->u.real.e = 4;
1256 break;
1257 default:
1258 internal_error (&dtp->common, "bad real kind");
1259 break;
1260 }
1261 }
1262 /* Output a real number with default format.
1263 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
1264 1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
1265
1266 void
1267 write_real (st_parameter_dt *dtp, const char *source, int length)
1268 {
1269 fnode f ;
1270 int org_scale = dtp->u.p.scale_factor;
1271 dtp->u.p.scale_factor = 1;
1272 set_fnode_default (dtp, &f, length);
1273 write_float (dtp, &f, source , length);
1274 dtp->u.p.scale_factor = org_scale;
1275 }
1276
1277
1278 void
1279 write_real_g0 (st_parameter_dt *dtp, const char *source, int length, int d)
1280 {
1281 fnode f ;
1282 set_fnode_default (dtp, &f, length);
1283 if (d > 0)
1284 f.u.real.d = d;
1285 dtp->u.p.g0_no_blanks = 1;
1286 write_float (dtp, &f, source , length);
1287 dtp->u.p.g0_no_blanks = 0;
1288 }
1289
1290
1291 static void
1292 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1293 {
1294 char semi_comma =
1295 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1296
1297 if (write_char (dtp, '('))
1298 return;
1299 write_real (dtp, source, kind);
1300
1301 if (write_char (dtp, semi_comma))
1302 return;
1303 write_real (dtp, source + size / 2, kind);
1304
1305 write_char (dtp, ')');
1306 }
1307
1308
1309 /* Write the separator between items. */
1310
1311 static void
1312 write_separator (st_parameter_dt *dtp)
1313 {
1314 char *p;
1315
1316 p = write_block (dtp, options.separator_len);
1317 if (p == NULL)
1318 return;
1319
1320 memcpy (p, options.separator, options.separator_len);
1321 }
1322
1323
1324 /* Write an item with list formatting.
1325 TODO: handle skipping to the next record correctly, particularly
1326 with strings. */
1327
1328 static void
1329 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1330 size_t size)
1331 {
1332 if (dtp->u.p.current_unit == NULL)
1333 return;
1334
1335 if (dtp->u.p.first_item)
1336 {
1337 dtp->u.p.first_item = 0;
1338 write_char (dtp, ' ');
1339 }
1340 else
1341 {
1342 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1343 dtp->u.p.current_unit->delim_status != DELIM_NONE)
1344 write_separator (dtp);
1345 }
1346
1347 switch (type)
1348 {
1349 case BT_INTEGER:
1350 write_integer (dtp, p, kind);
1351 break;
1352 case BT_LOGICAL:
1353 write_logical (dtp, p, kind);
1354 break;
1355 case BT_CHARACTER:
1356 write_character (dtp, p, kind, size);
1357 break;
1358 case BT_REAL:
1359 write_real (dtp, p, kind);
1360 break;
1361 case BT_COMPLEX:
1362 write_complex (dtp, p, kind, size);
1363 break;
1364 default:
1365 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1366 }
1367
1368 dtp->u.p.char_flag = (type == BT_CHARACTER);
1369 }
1370
1371
1372 void
1373 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1374 size_t size, size_t nelems)
1375 {
1376 size_t elem;
1377 char *tmp;
1378 size_t stride = type == BT_CHARACTER ?
1379 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1380
1381 tmp = (char *) p;
1382
1383 /* Big loop over all the elements. */
1384 for (elem = 0; elem < nelems; elem++)
1385 {
1386 dtp->u.p.item_count++;
1387 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
1388 }
1389 }
1390
1391 /* NAMELIST OUTPUT
1392
1393 nml_write_obj writes a namelist object to the output stream. It is called
1394 recursively for derived type components:
1395 obj = is the namelist_info for the current object.
1396 offset = the offset relative to the address held by the object for
1397 derived type arrays.
1398 base = is the namelist_info of the derived type, when obj is a
1399 component.
1400 base_name = the full name for a derived type, including qualifiers
1401 if any.
1402 The returned value is a pointer to the object beyond the last one
1403 accessed, including nested derived types. Notice that the namelist is
1404 a linear linked list of objects, including derived types and their
1405 components. A tree, of sorts, is implied by the compound names of
1406 the derived type components and this is how this function recurses through
1407 the list. */
1408
1409 /* A generous estimate of the number of characters needed to print
1410 repeat counts and indices, including commas, asterices and brackets. */
1411
1412 #define NML_DIGITS 20
1413
1414 static void
1415 namelist_write_newline (st_parameter_dt *dtp)
1416 {
1417 if (!is_internal_unit (dtp))
1418 {
1419 #ifdef HAVE_CRLF
1420 write_character (dtp, "\r\n", 1, 2);
1421 #else
1422 write_character (dtp, "\n", 1, 1);
1423 #endif
1424 return;
1425 }
1426
1427 if (is_array_io (dtp))
1428 {
1429 gfc_offset record;
1430 int finished;
1431
1432 /* Now that the current record has been padded out,
1433 determine where the next record in the array is. */
1434 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
1435 &finished);
1436 if (finished)
1437 dtp->u.p.current_unit->endfile = AT_ENDFILE;
1438 else
1439 {
1440 /* Now seek to this record */
1441 record = record * dtp->u.p.current_unit->recl;
1442
1443 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
1444 {
1445 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
1446 return;
1447 }
1448
1449 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1450 }
1451 }
1452 else
1453 write_character (dtp, " ", 1, 1);
1454 }
1455
1456
1457 static namelist_info *
1458 nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
1459 namelist_info * base, char * base_name)
1460 {
1461 int rep_ctr;
1462 int num;
1463 int nml_carry;
1464 int len;
1465 index_type obj_size;
1466 index_type nelem;
1467 size_t dim_i;
1468 size_t clen;
1469 index_type elem_ctr;
1470 size_t obj_name_len;
1471 void * p ;
1472 char cup;
1473 char * obj_name;
1474 char * ext_name;
1475 char rep_buff[NML_DIGITS];
1476 namelist_info * cmp;
1477 namelist_info * retval = obj->next;
1478 size_t base_name_len;
1479 size_t base_var_name_len;
1480 size_t tot_len;
1481 unit_delim tmp_delim;
1482
1483 /* Set the character to be used to separate values
1484 to a comma or semi-colon. */
1485
1486 char semi_comma =
1487 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1488
1489 /* Write namelist variable names in upper case. If a derived type,
1490 nothing is output. If a component, base and base_name are set. */
1491
1492 if (obj->type != GFC_DTYPE_DERIVED)
1493 {
1494 namelist_write_newline (dtp);
1495 write_character (dtp, " ", 1, 1);
1496
1497 len = 0;
1498 if (base)
1499 {
1500 len = strlen (base->var_name);
1501 base_name_len = strlen (base_name);
1502 for (dim_i = 0; dim_i < base_name_len; dim_i++)
1503 {
1504 cup = toupper (base_name[dim_i]);
1505 write_character (dtp, &cup, 1, 1);
1506 }
1507 }
1508 clen = strlen (obj->var_name);
1509 for (dim_i = len; dim_i < clen; dim_i++)
1510 {
1511 cup = toupper (obj->var_name[dim_i]);
1512 write_character (dtp, &cup, 1, 1);
1513 }
1514 write_character (dtp, "=", 1, 1);
1515 }
1516
1517 /* Counts the number of data output on a line, including names. */
1518
1519 num = 1;
1520
1521 len = obj->len;
1522
1523 switch (obj->type)
1524 {
1525
1526 case GFC_DTYPE_REAL:
1527 obj_size = size_from_real_kind (len);
1528 break;
1529
1530 case GFC_DTYPE_COMPLEX:
1531 obj_size = size_from_complex_kind (len);
1532 break;
1533
1534 case GFC_DTYPE_CHARACTER:
1535 obj_size = obj->string_length;
1536 break;
1537
1538 default:
1539 obj_size = len;
1540 }
1541
1542 if (obj->var_rank)
1543 obj_size = obj->size;
1544
1545 /* Set the index vector and count the number of elements. */
1546
1547 nelem = 1;
1548 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1549 {
1550 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
1551 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
1552 }
1553
1554 /* Main loop to output the data held in the object. */
1555
1556 rep_ctr = 1;
1557 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
1558 {
1559
1560 /* Build the pointer to the data value. The offset is passed by
1561 recursive calls to this function for arrays of derived types.
1562 Is NULL otherwise. */
1563
1564 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
1565 p += offset;
1566
1567 /* Check for repeat counts of intrinsic types. */
1568
1569 if ((elem_ctr < (nelem - 1)) &&
1570 (obj->type != GFC_DTYPE_DERIVED) &&
1571 !memcmp (p, (void*)(p + obj_size ), obj_size ))
1572 {
1573 rep_ctr++;
1574 }
1575
1576 /* Execute a repeated output. Note the flag no_leading_blank that
1577 is used in the functions used to output the intrinsic types. */
1578
1579 else
1580 {
1581 if (rep_ctr > 1)
1582 {
1583 sprintf(rep_buff, " %d*", rep_ctr);
1584 write_character (dtp, rep_buff, 1, strlen (rep_buff));
1585 dtp->u.p.no_leading_blank = 1;
1586 }
1587 num++;
1588
1589 /* Output the data, if an intrinsic type, or recurse into this
1590 routine to treat derived types. */
1591
1592 switch (obj->type)
1593 {
1594
1595 case GFC_DTYPE_INTEGER:
1596 write_integer (dtp, p, len);
1597 break;
1598
1599 case GFC_DTYPE_LOGICAL:
1600 write_logical (dtp, p, len);
1601 break;
1602
1603 case GFC_DTYPE_CHARACTER:
1604 tmp_delim = dtp->u.p.current_unit->delim_status;
1605 if (dtp->u.p.nml_delim == '"')
1606 dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
1607 if (dtp->u.p.nml_delim == '\'')
1608 dtp->u.p.current_unit->delim_status = DELIM_APOSTROPHE;
1609 write_character (dtp, p, 1, obj->string_length);
1610 dtp->u.p.current_unit->delim_status = tmp_delim;
1611 break;
1612
1613 case GFC_DTYPE_REAL:
1614 write_real (dtp, p, len);
1615 break;
1616
1617 case GFC_DTYPE_COMPLEX:
1618 dtp->u.p.no_leading_blank = 0;
1619 num++;
1620 write_complex (dtp, p, len, obj_size);
1621 break;
1622
1623 case GFC_DTYPE_DERIVED:
1624
1625 /* To treat a derived type, we need to build two strings:
1626 ext_name = the name, including qualifiers that prepends
1627 component names in the output - passed to
1628 nml_write_obj.
1629 obj_name = the derived type name with no qualifiers but %
1630 appended. This is used to identify the
1631 components. */
1632
1633 /* First ext_name => get length of all possible components */
1634
1635 base_name_len = base_name ? strlen (base_name) : 0;
1636 base_var_name_len = base ? strlen (base->var_name) : 0;
1637 ext_name = (char*)get_mem ( base_name_len
1638 + base_var_name_len
1639 + strlen (obj->var_name)
1640 + obj->var_rank * NML_DIGITS
1641 + 1);
1642
1643 memcpy (ext_name, base_name, base_name_len);
1644 clen = strlen (obj->var_name + base_var_name_len);
1645 memcpy (ext_name + base_name_len,
1646 obj->var_name + base_var_name_len, clen);
1647
1648 /* Append the qualifier. */
1649
1650 tot_len = base_name_len + clen;
1651 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1652 {
1653 if (!dim_i)
1654 {
1655 ext_name[tot_len] = '(';
1656 tot_len++;
1657 }
1658 sprintf (ext_name + tot_len, "%d", (int) obj->ls[dim_i].idx);
1659 tot_len += strlen (ext_name + tot_len);
1660 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
1661 tot_len++;
1662 }
1663
1664 ext_name[tot_len] = '\0';
1665
1666 /* Now obj_name. */
1667
1668 obj_name_len = strlen (obj->var_name) + 1;
1669 obj_name = get_mem (obj_name_len+1);
1670 memcpy (obj_name, obj->var_name, obj_name_len-1);
1671 memcpy (obj_name + obj_name_len-1, "%", 2);
1672
1673 /* Now loop over the components. Update the component pointer
1674 with the return value from nml_write_obj => this loop jumps
1675 past nested derived types. */
1676
1677 for (cmp = obj->next;
1678 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
1679 cmp = retval)
1680 {
1681 retval = nml_write_obj (dtp, cmp,
1682 (index_type)(p - obj->mem_pos),
1683 obj, ext_name);
1684 }
1685
1686 free (obj_name);
1687 free (ext_name);
1688 goto obj_loop;
1689
1690 default:
1691 internal_error (&dtp->common, "Bad type for namelist write");
1692 }
1693
1694 /* Reset the leading blank suppression, write a comma (or semi-colon)
1695 and, if 5 values have been output, write a newline and advance
1696 to column 2. Reset the repeat counter. */
1697
1698 dtp->u.p.no_leading_blank = 0;
1699 write_character (dtp, &semi_comma, 1, 1);
1700 if (num > 5)
1701 {
1702 num = 0;
1703 namelist_write_newline (dtp);
1704 write_character (dtp, " ", 1, 1);
1705 }
1706 rep_ctr = 1;
1707 }
1708
1709 /* Cycle through and increment the index vector. */
1710
1711 obj_loop:
1712
1713 nml_carry = 1;
1714 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
1715 {
1716 obj->ls[dim_i].idx += nml_carry ;
1717 nml_carry = 0;
1718 if (obj->ls[dim_i].idx > (ssize_t) GFC_DESCRIPTOR_UBOUND(obj,dim_i))
1719 {
1720 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
1721 nml_carry = 1;
1722 }
1723 }
1724 }
1725
1726 /* Return a pointer beyond the furthest object accessed. */
1727
1728 return retval;
1729 }
1730
1731
1732 /* This is the entry function for namelist writes. It outputs the name
1733 of the namelist and iterates through the namelist by calls to
1734 nml_write_obj. The call below has dummys in the arguments used in
1735 the treatment of derived types. */
1736
1737 void
1738 namelist_write (st_parameter_dt *dtp)
1739 {
1740 namelist_info * t1, *t2, *dummy = NULL;
1741 index_type i;
1742 index_type dummy_offset = 0;
1743 char c;
1744 char * dummy_name = NULL;
1745 unit_delim tmp_delim = DELIM_UNSPECIFIED;
1746
1747 /* Set the delimiter for namelist output. */
1748 tmp_delim = dtp->u.p.current_unit->delim_status;
1749
1750 dtp->u.p.nml_delim = tmp_delim == DELIM_APOSTROPHE ? '\'' : '"';
1751
1752 /* Temporarily disable namelist delimters. */
1753 dtp->u.p.current_unit->delim_status = DELIM_NONE;
1754
1755 write_character (dtp, "&", 1, 1);
1756
1757 /* Write namelist name in upper case - f95 std. */
1758 for (i = 0 ;i < dtp->namelist_name_len ;i++ )
1759 {
1760 c = toupper (dtp->namelist_name[i]);
1761 write_character (dtp, &c, 1 ,1);
1762 }
1763
1764 if (dtp->u.p.ionml != NULL)
1765 {
1766 t1 = dtp->u.p.ionml;
1767 while (t1 != NULL)
1768 {
1769 t2 = t1;
1770 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
1771 }
1772 }
1773
1774 namelist_write_newline (dtp);
1775 write_character (dtp, " /", 1, 2);
1776 /* Restore the original delimiter. */
1777 dtp->u.p.current_unit->delim_status = tmp_delim;
1778 }
1779
1780 #undef NML_DIGITS