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