annotate libgfortran/io/write.c @ 131:84e7813d76e9

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