* config/sh/linux-atomic.asm (ATOMIC_BOOL_COMPARE_AND_SWAP,
[official-gcc.git] / libgfortran / io / write.c
blob4956da8cf80807026b048c22ea4985931ebe8dec
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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
7 This file is part of the GNU Fortran 95 runtime library (libgfortran).
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.
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.
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.
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/>. */
28 #include "io.h"
29 #include <assert.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <stdlib.h>
33 #include <stdbool.h>
34 #include <errno.h>
35 #define star_fill(p, n) memset(p, '*', n)
37 #include "write_float.def"
39 typedef unsigned char uchar;
41 /* Write out default char4. */
43 static void
44 write_default_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
45 int src_len, int w_len)
47 char *p;
48 int j, k = 0;
49 gfc_char4_t c;
50 uchar d;
52 /* Take care of preceding blanks. */
53 if (w_len > src_len)
55 k = w_len - src_len;
56 p = write_block (dtp, k);
57 if (p == NULL)
58 return;
59 memset (p, ' ', k);
62 /* Get ready to handle delimiters if needed. */
63 switch (dtp->u.p.current_unit->delim_status)
65 case DELIM_APOSTROPHE:
66 d = '\'';
67 break;
68 case DELIM_QUOTE:
69 d = '"';
70 break;
71 default:
72 d = ' ';
73 break;
76 /* Now process the remaining characters, one at a time. */
77 for (j = k; j < src_len; j++)
79 c = source[j];
81 /* Handle delimiters if any. */
82 if (c == d && d != ' ')
84 p = write_block (dtp, 2);
85 if (p == NULL)
86 return;
87 *p++ = (uchar) c;
89 else
91 p = write_block (dtp, 1);
92 if (p == NULL)
93 return;
95 *p = c > 255 ? '?' : (uchar) c;
100 /* Write out UTF-8 converted from char4. */
102 static void
103 write_utf8_char4 (st_parameter_dt *dtp, gfc_char4_t *source,
104 int src_len, int w_len)
106 char *p;
107 int j, k = 0;
108 gfc_char4_t c;
109 static const uchar masks[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
110 static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
111 int nbytes;
112 uchar buf[6], d, *q;
114 /* Take care of preceding blanks. */
115 if (w_len > src_len)
117 k = w_len - src_len;
118 p = write_block (dtp, k);
119 if (p == NULL)
120 return;
121 memset (p, ' ', k);
124 /* Get ready to handle delimiters if needed. */
125 switch (dtp->u.p.current_unit->delim_status)
127 case DELIM_APOSTROPHE:
128 d = '\'';
129 break;
130 case DELIM_QUOTE:
131 d = '"';
132 break;
133 default:
134 d = ' ';
135 break;
138 /* Now process the remaining characters, one at a time. */
139 for (j = k; j < src_len; j++)
141 c = source[j];
142 if (c < 0x80)
144 /* Handle the delimiters if any. */
145 if (c == d && d != ' ')
147 p = write_block (dtp, 2);
148 if (p == NULL)
149 return;
150 *p++ = (uchar) c;
152 else
154 p = write_block (dtp, 1);
155 if (p == NULL)
156 return;
158 *p = (uchar) c;
160 else
162 /* Convert to UTF-8 sequence. */
163 nbytes = 1;
164 q = &buf[6];
168 *--q = ((c & 0x3F) | 0x80);
169 c >>= 6;
170 nbytes++;
172 while (c >= 0x3F || (c & limits[nbytes-1]));
174 *--q = (c | masks[nbytes-1]);
176 p = write_block (dtp, nbytes);
177 if (p == NULL)
178 return;
180 while (q < &buf[6])
181 *p++ = *q++;
187 void
188 write_a (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
190 int wlen;
191 char *p;
193 wlen = f->u.string.length < 0
194 || (f->format == FMT_G && f->u.string.length == 0)
195 ? len : f->u.string.length;
197 #ifdef HAVE_CRLF
198 /* If this is formatted STREAM IO convert any embedded line feed characters
199 to CR_LF on systems that use that sequence for newlines. See F2003
200 Standard sections 10.6.3 and 9.9 for further information. */
201 if (is_stream_io (dtp))
203 const char crlf[] = "\r\n";
204 int i, q, bytes;
205 q = bytes = 0;
207 /* Write out any padding if needed. */
208 if (len < wlen)
210 p = write_block (dtp, wlen - len);
211 if (p == NULL)
212 return;
213 memset (p, ' ', wlen - len);
216 /* Scan the source string looking for '\n' and convert it if found. */
217 for (i = 0; i < wlen; i++)
219 if (source[i] == '\n')
221 /* Write out the previously scanned characters in the string. */
222 if (bytes > 0)
224 p = write_block (dtp, bytes);
225 if (p == NULL)
226 return;
227 memcpy (p, &source[q], bytes);
228 q += bytes;
229 bytes = 0;
232 /* Write out the CR_LF sequence. */
233 q++;
234 p = write_block (dtp, 2);
235 if (p == NULL)
236 return;
237 memcpy (p, crlf, 2);
239 else
240 bytes++;
243 /* Write out any remaining bytes if no LF was found. */
244 if (bytes > 0)
246 p = write_block (dtp, bytes);
247 if (p == NULL)
248 return;
249 memcpy (p, &source[q], bytes);
252 else
254 #endif
255 p = write_block (dtp, wlen);
256 if (p == NULL)
257 return;
259 if (wlen < len)
260 memcpy (p, source, wlen);
261 else
263 memset (p, ' ', wlen - len);
264 memcpy (p + wlen - len, source, len);
266 #ifdef HAVE_CRLF
268 #endif
272 /* The primary difference between write_a_char4 and write_a is that we have to
273 deal with writing from the first byte of the 4-byte character and pay
274 attention to the most significant bytes. For ENCODING="default" write the
275 lowest significant byte. If the 3 most significant bytes contain
276 non-zero values, emit a '?'. For ENCODING="utf-8", convert the UCS-32 value
277 to the UTF-8 encoded string before writing out. */
279 void
280 write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
282 int wlen;
283 gfc_char4_t *q;
285 wlen = f->u.string.length < 0
286 || (f->format == FMT_G && f->u.string.length == 0)
287 ? len : f->u.string.length;
289 q = (gfc_char4_t *) source;
290 #ifdef HAVE_CRLF
291 /* If this is formatted STREAM IO convert any embedded line feed characters
292 to CR_LF on systems that use that sequence for newlines. See F2003
293 Standard sections 10.6.3 and 9.9 for further information. */
294 if (is_stream_io (dtp))
296 const char crlf[] = "\r\n";
297 int i, bytes;
298 gfc_char4_t *qq;
299 bytes = 0;
301 /* Write out any padding if needed. */
302 if (len < wlen)
304 char *p;
305 p = write_block (dtp, wlen - len);
306 if (p == NULL)
307 return;
308 memset (p, ' ', wlen - len);
311 /* Scan the source string looking for '\n' and convert it if found. */
312 qq = (gfc_char4_t *) source;
313 for (i = 0; i < wlen; i++)
315 if (qq[i] == '\n')
317 /* Write out the previously scanned characters in the string. */
318 if (bytes > 0)
320 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
321 write_utf8_char4 (dtp, q, bytes, 0);
322 else
323 write_default_char4 (dtp, q, bytes, 0);
324 bytes = 0;
327 /* Write out the CR_LF sequence. */
328 write_default_char4 (dtp, crlf, 2, 0);
330 else
331 bytes++;
334 /* Write out any remaining bytes if no LF was found. */
335 if (bytes > 0)
337 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
338 write_utf8_char4 (dtp, q, bytes, 0);
339 else
340 write_default_char4 (dtp, q, bytes, 0);
343 else
345 #endif
346 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
347 write_utf8_char4 (dtp, q, len, wlen);
348 else
349 write_default_char4 (dtp, q, len, wlen);
350 #ifdef HAVE_CRLF
352 #endif
356 static GFC_INTEGER_LARGEST
357 extract_int (const void *p, int len)
359 GFC_INTEGER_LARGEST i = 0;
361 if (p == NULL)
362 return i;
364 switch (len)
366 case 1:
368 GFC_INTEGER_1 tmp;
369 memcpy ((void *) &tmp, p, len);
370 i = tmp;
372 break;
373 case 2:
375 GFC_INTEGER_2 tmp;
376 memcpy ((void *) &tmp, p, len);
377 i = tmp;
379 break;
380 case 4:
382 GFC_INTEGER_4 tmp;
383 memcpy ((void *) &tmp, p, len);
384 i = tmp;
386 break;
387 case 8:
389 GFC_INTEGER_8 tmp;
390 memcpy ((void *) &tmp, p, len);
391 i = tmp;
393 break;
394 #ifdef HAVE_GFC_INTEGER_16
395 case 16:
397 GFC_INTEGER_16 tmp;
398 memcpy ((void *) &tmp, p, len);
399 i = tmp;
401 break;
402 #endif
403 default:
404 internal_error (NULL, "bad integer kind");
407 return i;
410 static GFC_UINTEGER_LARGEST
411 extract_uint (const void *p, int len)
413 GFC_UINTEGER_LARGEST i = 0;
415 if (p == NULL)
416 return i;
418 switch (len)
420 case 1:
422 GFC_INTEGER_1 tmp;
423 memcpy ((void *) &tmp, p, len);
424 i = (GFC_UINTEGER_1) tmp;
426 break;
427 case 2:
429 GFC_INTEGER_2 tmp;
430 memcpy ((void *) &tmp, p, len);
431 i = (GFC_UINTEGER_2) tmp;
433 break;
434 case 4:
436 GFC_INTEGER_4 tmp;
437 memcpy ((void *) &tmp, p, len);
438 i = (GFC_UINTEGER_4) tmp;
440 break;
441 case 8:
443 GFC_INTEGER_8 tmp;
444 memcpy ((void *) &tmp, p, len);
445 i = (GFC_UINTEGER_8) tmp;
447 break;
448 #ifdef HAVE_GFC_INTEGER_16
449 case 16:
451 GFC_INTEGER_16 tmp;
452 memcpy ((void *) &tmp, p, len);
453 i = (GFC_UINTEGER_16) tmp;
455 break;
456 #endif
457 default:
458 internal_error (NULL, "bad integer kind");
461 return i;
465 void
466 write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
468 char *p;
469 int wlen;
470 GFC_INTEGER_LARGEST n;
472 wlen = (f->format == FMT_G && f->u.w == 0) ? 1 : f->u.w;
474 p = write_block (dtp, wlen);
475 if (p == NULL)
476 return;
478 memset (p, ' ', wlen - 1);
479 n = extract_int (source, len);
480 p[wlen - 1] = (n) ? 'T' : 'F';
484 static void
485 write_int (st_parameter_dt *dtp, const fnode *f, const char *source, int len,
486 const char *(*conv) (GFC_UINTEGER_LARGEST, char *, size_t))
488 GFC_UINTEGER_LARGEST n = 0;
489 int w, m, digits, nzero, nblank;
490 char *p;
491 const char *q;
492 char itoa_buf[GFC_BTOA_BUF_SIZE];
494 w = f->u.integer.w;
495 m = f->u.integer.m;
497 n = extract_uint (source, len);
499 /* Special case: */
501 if (m == 0 && n == 0)
503 if (w == 0)
504 w = 1;
506 p = write_block (dtp, w);
507 if (p == NULL)
508 return;
510 memset (p, ' ', w);
511 goto done;
514 q = conv (n, itoa_buf, sizeof (itoa_buf));
515 digits = strlen (q);
517 /* Select a width if none was specified. The idea here is to always
518 print something. */
520 if (w == 0)
521 w = ((digits < m) ? m : digits);
523 p = write_block (dtp, w);
524 if (p == NULL)
525 return;
527 nzero = 0;
528 if (digits < m)
529 nzero = m - digits;
531 /* See if things will work. */
533 nblank = w - (nzero + digits);
535 if (nblank < 0)
537 star_fill (p, w);
538 goto done;
542 if (!dtp->u.p.no_leading_blank)
544 memset (p, ' ', nblank);
545 p += nblank;
546 memset (p, '0', nzero);
547 p += nzero;
548 memcpy (p, q, digits);
550 else
552 memset (p, '0', nzero);
553 p += nzero;
554 memcpy (p, q, digits);
555 p += digits;
556 memset (p, ' ', nblank);
557 dtp->u.p.no_leading_blank = 0;
560 done:
561 return;
564 static void
565 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
566 int len,
567 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
569 GFC_INTEGER_LARGEST n = 0;
570 int w, m, digits, nsign, nzero, nblank;
571 char *p;
572 const char *q;
573 sign_t sign;
574 char itoa_buf[GFC_BTOA_BUF_SIZE];
576 w = f->u.integer.w;
577 m = f->format == FMT_G ? -1 : f->u.integer.m;
579 n = extract_int (source, len);
581 /* Special case: */
582 if (m == 0 && n == 0)
584 if (w == 0)
585 w = 1;
587 p = write_block (dtp, w);
588 if (p == NULL)
589 return;
591 memset (p, ' ', w);
592 goto done;
595 sign = calculate_sign (dtp, n < 0);
596 if (n < 0)
597 n = -n;
598 nsign = sign == S_NONE ? 0 : 1;
600 /* conv calls itoa which sets the negative sign needed
601 by write_integer. The sign '+' or '-' is set below based on sign
602 calculated above, so we just point past the sign in the string
603 before proceeding to avoid double signs in corner cases.
604 (see PR38504) */
605 q = conv (n, itoa_buf, sizeof (itoa_buf));
606 if (*q == '-')
607 q++;
609 digits = strlen (q);
611 /* Select a width if none was specified. The idea here is to always
612 print something. */
614 if (w == 0)
615 w = ((digits < m) ? m : digits) + nsign;
617 p = write_block (dtp, w);
618 if (p == NULL)
619 return;
621 nzero = 0;
622 if (digits < m)
623 nzero = m - digits;
625 /* See if things will work. */
627 nblank = w - (nsign + nzero + digits);
629 if (nblank < 0)
631 star_fill (p, w);
632 goto done;
635 memset (p, ' ', nblank);
636 p += nblank;
638 switch (sign)
640 case S_PLUS:
641 *p++ = '+';
642 break;
643 case S_MINUS:
644 *p++ = '-';
645 break;
646 case S_NONE:
647 break;
650 memset (p, '0', nzero);
651 p += nzero;
653 memcpy (p, q, digits);
655 done:
656 return;
660 /* Convert unsigned octal to ascii. */
662 static const char *
663 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
665 char *p;
667 assert (len >= GFC_OTOA_BUF_SIZE);
669 if (n == 0)
670 return "0";
672 p = buffer + GFC_OTOA_BUF_SIZE - 1;
673 *p = '\0';
675 while (n != 0)
677 *--p = '0' + (n & 7);
678 n >>= 3;
681 return p;
685 /* Convert unsigned binary to ascii. */
687 static const char *
688 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
690 char *p;
692 assert (len >= GFC_BTOA_BUF_SIZE);
694 if (n == 0)
695 return "0";
697 p = buffer + GFC_BTOA_BUF_SIZE - 1;
698 *p = '\0';
700 while (n != 0)
702 *--p = '0' + (n & 1);
703 n >>= 1;
706 return p;
710 /* gfc_itoa()-- Integer to decimal conversion.
711 The itoa function is a widespread non-standard extension to standard
712 C, often declared in <stdlib.h>. Even though the itoa defined here
713 is a static function we take care not to conflict with any prior
714 non-static declaration. Hence the 'gfc_' prefix, which is normally
715 reserved for functions with external linkage. */
717 static const char *
718 gfc_itoa (GFC_INTEGER_LARGEST n, char *buffer, size_t len)
720 int negative;
721 char *p;
722 GFC_UINTEGER_LARGEST t;
724 assert (len >= GFC_ITOA_BUF_SIZE);
726 if (n == 0)
727 return "0";
729 negative = 0;
730 t = n;
731 if (n < 0)
733 negative = 1;
734 t = -n; /*must use unsigned to protect from overflow*/
737 p = buffer + GFC_ITOA_BUF_SIZE - 1;
738 *p = '\0';
740 while (t != 0)
742 *--p = '0' + (t % 10);
743 t /= 10;
746 if (negative)
747 *--p = '-';
748 return p;
752 void
753 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
755 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
759 void
760 write_b (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
762 write_int (dtp, f, p, len, btoa);
766 void
767 write_o (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
769 write_int (dtp, f, p, len, otoa);
772 void
773 write_z (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
775 write_int (dtp, f, p, len, gfc_xtoa);
779 void
780 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
782 write_float (dtp, f, p, len);
786 void
787 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
789 write_float (dtp, f, p, len);
793 void
794 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
796 write_float (dtp, f, p, len);
800 void
801 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
803 write_float (dtp, f, p, len);
807 void
808 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
810 write_float (dtp, f, p, len);
814 /* Take care of the X/TR descriptor. */
816 void
817 write_x (st_parameter_dt *dtp, int len, int nspaces)
819 char *p;
821 p = write_block (dtp, len);
822 if (p == NULL)
823 return;
824 if (nspaces > 0 && len - nspaces >= 0)
825 memset (&p[len - nspaces], ' ', nspaces);
829 /* List-directed writing. */
832 /* Write a single character to the output. Returns nonzero if
833 something goes wrong. */
835 static int
836 write_char (st_parameter_dt *dtp, char c)
838 char *p;
840 p = write_block (dtp, 1);
841 if (p == NULL)
842 return 1;
844 *p = c;
846 return 0;
850 /* Write a list-directed logical value. */
852 static void
853 write_logical (st_parameter_dt *dtp, const char *source, int length)
855 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
859 /* Write a list-directed integer value. */
861 static void
862 write_integer (st_parameter_dt *dtp, const char *source, int length)
864 char *p;
865 const char *q;
866 int digits;
867 int width;
868 char itoa_buf[GFC_ITOA_BUF_SIZE];
870 q = gfc_itoa (extract_int (source, length), itoa_buf, sizeof (itoa_buf));
872 switch (length)
874 case 1:
875 width = 4;
876 break;
878 case 2:
879 width = 6;
880 break;
882 case 4:
883 width = 11;
884 break;
886 case 8:
887 width = 20;
888 break;
890 default:
891 width = 0;
892 break;
895 digits = strlen (q);
897 if (width < digits)
898 width = digits;
899 p = write_block (dtp, width);
900 if (p == NULL)
901 return;
902 if (dtp->u.p.no_leading_blank)
904 memcpy (p, q, digits);
905 memset (p + digits, ' ', width - digits);
907 else
909 memset (p, ' ', width - digits);
910 memcpy (p + width - digits, q, digits);
915 /* Write a list-directed string. We have to worry about delimiting
916 the strings if the file has been opened in that mode. */
918 static void
919 write_character (st_parameter_dt *dtp, const char *source, int kind, int length)
921 int i, extra;
922 char *p, d;
924 switch (dtp->u.p.current_unit->delim_status)
926 case DELIM_APOSTROPHE:
927 d = '\'';
928 break;
929 case DELIM_QUOTE:
930 d = '"';
931 break;
932 default:
933 d = ' ';
934 break;
937 if (kind == 1)
939 if (d == ' ')
940 extra = 0;
941 else
943 extra = 2;
945 for (i = 0; i < length; i++)
946 if (source[i] == d)
947 extra++;
950 p = write_block (dtp, length + extra);
951 if (p == NULL)
952 return;
954 if (d == ' ')
955 memcpy (p, source, length);
956 else
958 *p++ = d;
960 for (i = 0; i < length; i++)
962 *p++ = source[i];
963 if (source[i] == d)
964 *p++ = d;
967 *p = d;
970 else
972 if (d == ' ')
974 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
975 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
976 else
977 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
979 else
981 p = write_block (dtp, 1);
982 *p = d;
984 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
985 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
986 else
987 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
989 p = write_block (dtp, 1);
990 *p = d;
996 /* Set an fnode to default format. */
998 static void
999 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
1001 f->format = FMT_G;
1002 switch (length)
1004 case 4:
1005 f->u.real.w = 15;
1006 f->u.real.d = 8;
1007 f->u.real.e = 2;
1008 break;
1009 case 8:
1010 f->u.real.w = 25;
1011 f->u.real.d = 17;
1012 f->u.real.e = 3;
1013 break;
1014 case 10:
1015 f->u.real.w = 29;
1016 f->u.real.d = 20;
1017 f->u.real.e = 4;
1018 break;
1019 case 16:
1020 f->u.real.w = 44;
1021 f->u.real.d = 35;
1022 f->u.real.e = 4;
1023 break;
1024 default:
1025 internal_error (&dtp->common, "bad real kind");
1026 break;
1029 /* Output a real number with default format.
1030 This is 1PG14.7E2 for REAL(4), 1PG23.15E3 for REAL(8),
1031 1PG28.19E4 for REAL(10) and 1PG43.34E4 for REAL(16). */
1033 void
1034 write_real (st_parameter_dt *dtp, const char *source, int length)
1036 fnode f ;
1037 int org_scale = dtp->u.p.scale_factor;
1038 dtp->u.p.scale_factor = 1;
1039 set_fnode_default (dtp, &f, length);
1040 write_float (dtp, &f, source , length);
1041 dtp->u.p.scale_factor = org_scale;
1045 void
1046 write_real_g0 (st_parameter_dt *dtp, const char *source, int length, int d)
1048 fnode f ;
1049 set_fnode_default (dtp, &f, length);
1050 if (d > 0)
1051 f.u.real.d = d;
1052 dtp->u.p.g0_no_blanks = 1;
1053 write_float (dtp, &f, source , length);
1054 dtp->u.p.g0_no_blanks = 0;
1058 static void
1059 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
1061 char semi_comma =
1062 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1064 if (write_char (dtp, '('))
1065 return;
1066 write_real (dtp, source, kind);
1068 if (write_char (dtp, semi_comma))
1069 return;
1070 write_real (dtp, source + size / 2, kind);
1072 write_char (dtp, ')');
1076 /* Write the separator between items. */
1078 static void
1079 write_separator (st_parameter_dt *dtp)
1081 char *p;
1083 p = write_block (dtp, options.separator_len);
1084 if (p == NULL)
1085 return;
1087 memcpy (p, options.separator, options.separator_len);
1091 /* Write an item with list formatting.
1092 TODO: handle skipping to the next record correctly, particularly
1093 with strings. */
1095 static void
1096 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
1097 size_t size)
1099 if (dtp->u.p.current_unit == NULL)
1100 return;
1102 if (dtp->u.p.first_item)
1104 dtp->u.p.first_item = 0;
1105 write_char (dtp, ' ');
1107 else
1109 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
1110 dtp->u.p.current_unit->delim_status != DELIM_NONE)
1111 write_separator (dtp);
1114 switch (type)
1116 case BT_INTEGER:
1117 write_integer (dtp, p, kind);
1118 break;
1119 case BT_LOGICAL:
1120 write_logical (dtp, p, kind);
1121 break;
1122 case BT_CHARACTER:
1123 write_character (dtp, p, kind, size);
1124 break;
1125 case BT_REAL:
1126 write_real (dtp, p, kind);
1127 break;
1128 case BT_COMPLEX:
1129 write_complex (dtp, p, kind, size);
1130 break;
1131 default:
1132 internal_error (&dtp->common, "list_formatted_write(): Bad type");
1135 dtp->u.p.char_flag = (type == BT_CHARACTER);
1139 void
1140 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1141 size_t size, size_t nelems)
1143 size_t elem;
1144 char *tmp;
1145 size_t stride = type == BT_CHARACTER ?
1146 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1148 tmp = (char *) p;
1150 /* Big loop over all the elements. */
1151 for (elem = 0; elem < nelems; elem++)
1153 dtp->u.p.item_count++;
1154 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
1158 /* NAMELIST OUTPUT
1160 nml_write_obj writes a namelist object to the output stream. It is called
1161 recursively for derived type components:
1162 obj = is the namelist_info for the current object.
1163 offset = the offset relative to the address held by the object for
1164 derived type arrays.
1165 base = is the namelist_info of the derived type, when obj is a
1166 component.
1167 base_name = the full name for a derived type, including qualifiers
1168 if any.
1169 The returned value is a pointer to the object beyond the last one
1170 accessed, including nested derived types. Notice that the namelist is
1171 a linear linked list of objects, including derived types and their
1172 components. A tree, of sorts, is implied by the compound names of
1173 the derived type components and this is how this function recurses through
1174 the list. */
1176 /* A generous estimate of the number of characters needed to print
1177 repeat counts and indices, including commas, asterices and brackets. */
1179 #define NML_DIGITS 20
1181 static void
1182 namelist_write_newline (st_parameter_dt *dtp)
1184 if (!is_internal_unit (dtp))
1186 #ifdef HAVE_CRLF
1187 write_character (dtp, "\r\n", 1, 2);
1188 #else
1189 write_character (dtp, "\n", 1, 1);
1190 #endif
1191 return;
1194 if (is_array_io (dtp))
1196 gfc_offset record;
1197 int finished, length;
1199 length = (int) dtp->u.p.current_unit->bytes_left;
1201 /* Now that the current record has been padded out,
1202 determine where the next record in the array is. */
1203 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
1204 &finished);
1205 if (finished)
1206 dtp->u.p.current_unit->endfile = AT_ENDFILE;
1207 else
1209 /* Now seek to this record */
1210 record = record * dtp->u.p.current_unit->recl;
1212 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
1214 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
1215 return;
1218 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
1221 else
1222 write_character (dtp, " ", 1, 1);
1226 static namelist_info *
1227 nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
1228 namelist_info * base, char * base_name)
1230 int rep_ctr;
1231 int num;
1232 int nml_carry;
1233 int len;
1234 index_type obj_size;
1235 index_type nelem;
1236 size_t dim_i;
1237 size_t clen;
1238 index_type elem_ctr;
1239 size_t obj_name_len;
1240 void * p ;
1241 char cup;
1242 char * obj_name;
1243 char * ext_name;
1244 char rep_buff[NML_DIGITS];
1245 namelist_info * cmp;
1246 namelist_info * retval = obj->next;
1247 size_t base_name_len;
1248 size_t base_var_name_len;
1249 size_t tot_len;
1250 unit_delim tmp_delim;
1252 /* Set the character to be used to separate values
1253 to a comma or semi-colon. */
1255 char semi_comma =
1256 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
1258 /* Write namelist variable names in upper case. If a derived type,
1259 nothing is output. If a component, base and base_name are set. */
1261 if (obj->type != GFC_DTYPE_DERIVED)
1263 namelist_write_newline (dtp);
1264 write_character (dtp, " ", 1, 1);
1266 len = 0;
1267 if (base)
1269 len = strlen (base->var_name);
1270 base_name_len = strlen (base_name);
1271 for (dim_i = 0; dim_i < base_name_len; dim_i++)
1273 cup = toupper (base_name[dim_i]);
1274 write_character (dtp, &cup, 1, 1);
1277 clen = strlen (obj->var_name);
1278 for (dim_i = len; dim_i < clen; dim_i++)
1280 cup = toupper (obj->var_name[dim_i]);
1281 write_character (dtp, &cup, 1, 1);
1283 write_character (dtp, "=", 1, 1);
1286 /* Counts the number of data output on a line, including names. */
1288 num = 1;
1290 len = obj->len;
1292 switch (obj->type)
1295 case GFC_DTYPE_REAL:
1296 obj_size = size_from_real_kind (len);
1297 break;
1299 case GFC_DTYPE_COMPLEX:
1300 obj_size = size_from_complex_kind (len);
1301 break;
1303 case GFC_DTYPE_CHARACTER:
1304 obj_size = obj->string_length;
1305 break;
1307 default:
1308 obj_size = len;
1311 if (obj->var_rank)
1312 obj_size = obj->size;
1314 /* Set the index vector and count the number of elements. */
1316 nelem = 1;
1317 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1319 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
1320 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
1323 /* Main loop to output the data held in the object. */
1325 rep_ctr = 1;
1326 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
1329 /* Build the pointer to the data value. The offset is passed by
1330 recursive calls to this function for arrays of derived types.
1331 Is NULL otherwise. */
1333 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
1334 p += offset;
1336 /* Check for repeat counts of intrinsic types. */
1338 if ((elem_ctr < (nelem - 1)) &&
1339 (obj->type != GFC_DTYPE_DERIVED) &&
1340 !memcmp (p, (void*)(p + obj_size ), obj_size ))
1342 rep_ctr++;
1345 /* Execute a repeated output. Note the flag no_leading_blank that
1346 is used in the functions used to output the intrinsic types. */
1348 else
1350 if (rep_ctr > 1)
1352 sprintf(rep_buff, " %d*", rep_ctr);
1353 write_character (dtp, rep_buff, 1, strlen (rep_buff));
1354 dtp->u.p.no_leading_blank = 1;
1356 num++;
1358 /* Output the data, if an intrinsic type, or recurse into this
1359 routine to treat derived types. */
1361 switch (obj->type)
1364 case GFC_DTYPE_INTEGER:
1365 write_integer (dtp, p, len);
1366 break;
1368 case GFC_DTYPE_LOGICAL:
1369 write_logical (dtp, p, len);
1370 break;
1372 case GFC_DTYPE_CHARACTER:
1373 tmp_delim = dtp->u.p.current_unit->delim_status;
1374 if (dtp->u.p.nml_delim == '"')
1375 dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
1376 if (dtp->u.p.nml_delim == '\'')
1377 dtp->u.p.current_unit->delim_status = DELIM_APOSTROPHE;
1378 write_character (dtp, p, 1, obj->string_length);
1379 dtp->u.p.current_unit->delim_status = tmp_delim;
1380 break;
1382 case GFC_DTYPE_REAL:
1383 write_real (dtp, p, len);
1384 break;
1386 case GFC_DTYPE_COMPLEX:
1387 dtp->u.p.no_leading_blank = 0;
1388 num++;
1389 write_complex (dtp, p, len, obj_size);
1390 break;
1392 case GFC_DTYPE_DERIVED:
1394 /* To treat a derived type, we need to build two strings:
1395 ext_name = the name, including qualifiers that prepends
1396 component names in the output - passed to
1397 nml_write_obj.
1398 obj_name = the derived type name with no qualifiers but %
1399 appended. This is used to identify the
1400 components. */
1402 /* First ext_name => get length of all possible components */
1404 base_name_len = base_name ? strlen (base_name) : 0;
1405 base_var_name_len = base ? strlen (base->var_name) : 0;
1406 ext_name = (char*)get_mem ( base_name_len
1407 + base_var_name_len
1408 + strlen (obj->var_name)
1409 + obj->var_rank * NML_DIGITS
1410 + 1);
1412 memcpy (ext_name, base_name, base_name_len);
1413 clen = strlen (obj->var_name + base_var_name_len);
1414 memcpy (ext_name + base_name_len,
1415 obj->var_name + base_var_name_len, clen);
1417 /* Append the qualifier. */
1419 tot_len = base_name_len + clen;
1420 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
1422 if (!dim_i)
1424 ext_name[tot_len] = '(';
1425 tot_len++;
1427 sprintf (ext_name + tot_len, "%d", (int) obj->ls[dim_i].idx);
1428 tot_len += strlen (ext_name + tot_len);
1429 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
1430 tot_len++;
1433 ext_name[tot_len] = '\0';
1435 /* Now obj_name. */
1437 obj_name_len = strlen (obj->var_name) + 1;
1438 obj_name = get_mem (obj_name_len+1);
1439 memcpy (obj_name, obj->var_name, obj_name_len-1);
1440 memcpy (obj_name + obj_name_len-1, "%", 2);
1442 /* Now loop over the components. Update the component pointer
1443 with the return value from nml_write_obj => this loop jumps
1444 past nested derived types. */
1446 for (cmp = obj->next;
1447 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
1448 cmp = retval)
1450 retval = nml_write_obj (dtp, cmp,
1451 (index_type)(p - obj->mem_pos),
1452 obj, ext_name);
1455 free_mem (obj_name);
1456 free_mem (ext_name);
1457 goto obj_loop;
1459 default:
1460 internal_error (&dtp->common, "Bad type for namelist write");
1463 /* Reset the leading blank suppression, write a comma (or semi-colon)
1464 and, if 5 values have been output, write a newline and advance
1465 to column 2. Reset the repeat counter. */
1467 dtp->u.p.no_leading_blank = 0;
1468 write_character (dtp, &semi_comma, 1, 1);
1469 if (num > 5)
1471 num = 0;
1472 namelist_write_newline (dtp);
1473 write_character (dtp, " ", 1, 1);
1475 rep_ctr = 1;
1478 /* Cycle through and increment the index vector. */
1480 obj_loop:
1482 nml_carry = 1;
1483 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
1485 obj->ls[dim_i].idx += nml_carry ;
1486 nml_carry = 0;
1487 if (obj->ls[dim_i].idx > (ssize_t) GFC_DESCRIPTOR_UBOUND(obj,dim_i))
1489 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
1490 nml_carry = 1;
1495 /* Return a pointer beyond the furthest object accessed. */
1497 return retval;
1501 /* This is the entry function for namelist writes. It outputs the name
1502 of the namelist and iterates through the namelist by calls to
1503 nml_write_obj. The call below has dummys in the arguments used in
1504 the treatment of derived types. */
1506 void
1507 namelist_write (st_parameter_dt *dtp)
1509 namelist_info * t1, *t2, *dummy = NULL;
1510 index_type i;
1511 index_type dummy_offset = 0;
1512 char c;
1513 char * dummy_name = NULL;
1514 unit_delim tmp_delim = DELIM_UNSPECIFIED;
1516 /* Set the delimiter for namelist output. */
1517 tmp_delim = dtp->u.p.current_unit->delim_status;
1519 dtp->u.p.nml_delim = tmp_delim == DELIM_APOSTROPHE ? '\'' : '"';
1521 /* Temporarily disable namelist delimters. */
1522 dtp->u.p.current_unit->delim_status = DELIM_NONE;
1524 write_character (dtp, "&", 1, 1);
1526 /* Write namelist name in upper case - f95 std. */
1527 for (i = 0 ;i < dtp->namelist_name_len ;i++ )
1529 c = toupper (dtp->namelist_name[i]);
1530 write_character (dtp, &c, 1 ,1);
1533 if (dtp->u.p.ionml != NULL)
1535 t1 = dtp->u.p.ionml;
1536 while (t1 != NULL)
1538 t2 = t1;
1539 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
1543 namelist_write_newline (dtp);
1544 write_character (dtp, " /", 1, 2);
1545 /* Restore the original delimiter. */
1546 dtp->u.p.current_unit->delim_status = tmp_delim;
1549 #undef NML_DIGITS