annotate libgfortran/io/write.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1 /* Copyright (C) 2002-2020 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 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
689 write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len)
111
kono
parents:
diff changeset
690 {
kono
parents:
diff changeset
691 int w, m, digits, nzero, nblank;
kono
parents:
diff changeset
692 char *p;
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 w = f->u.integer.w;
kono
parents:
diff changeset
695 m = f->u.integer.m;
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 /* Special case: */
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 if (m == 0 && n == 0)
kono
parents:
diff changeset
700 {
kono
parents:
diff changeset
701 if (w == 0)
kono
parents:
diff changeset
702 w = 1;
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 p = write_block (dtp, w);
kono
parents:
diff changeset
705 if (p == NULL)
kono
parents:
diff changeset
706 return;
kono
parents:
diff changeset
707 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
708 {
kono
parents:
diff changeset
709 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
710 memset4 (p4, ' ', w);
kono
parents:
diff changeset
711 }
kono
parents:
diff changeset
712 else
kono
parents:
diff changeset
713 memset (p, ' ', w);
kono
parents:
diff changeset
714 goto done;
kono
parents:
diff changeset
715 }
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 digits = strlen (q);
kono
parents:
diff changeset
718
kono
parents:
diff changeset
719 /* Select a width if none was specified. The idea here is to always
kono
parents:
diff changeset
720 print something. */
kono
parents:
diff changeset
721
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
722 if (w == DEFAULT_WIDTH)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
723 w = default_width_for_integer (len);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
724
111
kono
parents:
diff changeset
725 if (w == 0)
kono
parents:
diff changeset
726 w = ((digits < m) ? m : digits);
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 p = write_block (dtp, w);
kono
parents:
diff changeset
729 if (p == NULL)
kono
parents:
diff changeset
730 return;
kono
parents:
diff changeset
731
kono
parents:
diff changeset
732 nzero = 0;
kono
parents:
diff changeset
733 if (digits < m)
kono
parents:
diff changeset
734 nzero = m - digits;
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 /* See if things will work. */
kono
parents:
diff changeset
737
kono
parents:
diff changeset
738 nblank = w - (nzero + digits);
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
741 {
kono
parents:
diff changeset
742 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
743 if (nblank < 0)
kono
parents:
diff changeset
744 {
kono
parents:
diff changeset
745 memset4 (p4, '*', w);
kono
parents:
diff changeset
746 return;
kono
parents:
diff changeset
747 }
kono
parents:
diff changeset
748
kono
parents:
diff changeset
749 if (!dtp->u.p.no_leading_blank)
kono
parents:
diff changeset
750 {
kono
parents:
diff changeset
751 memset4 (p4, ' ', nblank);
kono
parents:
diff changeset
752 q += nblank;
kono
parents:
diff changeset
753 memset4 (p4, '0', nzero);
kono
parents:
diff changeset
754 q += nzero;
kono
parents:
diff changeset
755 memcpy4 (p4, q, digits);
kono
parents:
diff changeset
756 }
kono
parents:
diff changeset
757 else
kono
parents:
diff changeset
758 {
kono
parents:
diff changeset
759 memset4 (p4, '0', nzero);
kono
parents:
diff changeset
760 q += nzero;
kono
parents:
diff changeset
761 memcpy4 (p4, q, digits);
kono
parents:
diff changeset
762 q += digits;
kono
parents:
diff changeset
763 memset4 (p4, ' ', nblank);
kono
parents:
diff changeset
764 dtp->u.p.no_leading_blank = 0;
kono
parents:
diff changeset
765 }
kono
parents:
diff changeset
766 return;
kono
parents:
diff changeset
767 }
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 if (nblank < 0)
kono
parents:
diff changeset
770 {
kono
parents:
diff changeset
771 star_fill (p, w);
kono
parents:
diff changeset
772 goto done;
kono
parents:
diff changeset
773 }
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 if (!dtp->u.p.no_leading_blank)
kono
parents:
diff changeset
776 {
kono
parents:
diff changeset
777 memset (p, ' ', nblank);
kono
parents:
diff changeset
778 p += nblank;
kono
parents:
diff changeset
779 memset (p, '0', nzero);
kono
parents:
diff changeset
780 p += nzero;
kono
parents:
diff changeset
781 memcpy (p, q, digits);
kono
parents:
diff changeset
782 }
kono
parents:
diff changeset
783 else
kono
parents:
diff changeset
784 {
kono
parents:
diff changeset
785 memset (p, '0', nzero);
kono
parents:
diff changeset
786 p += nzero;
kono
parents:
diff changeset
787 memcpy (p, q, digits);
kono
parents:
diff changeset
788 p += digits;
kono
parents:
diff changeset
789 memset (p, ' ', nblank);
kono
parents:
diff changeset
790 dtp->u.p.no_leading_blank = 0;
kono
parents:
diff changeset
791 }
kono
parents:
diff changeset
792
kono
parents:
diff changeset
793 done:
kono
parents:
diff changeset
794 return;
kono
parents:
diff changeset
795 }
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 static void
kono
parents:
diff changeset
798 write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
kono
parents:
diff changeset
799 int len,
kono
parents:
diff changeset
800 const char *(*conv) (GFC_INTEGER_LARGEST, char *, size_t))
kono
parents:
diff changeset
801 {
kono
parents:
diff changeset
802 GFC_INTEGER_LARGEST n = 0;
kono
parents:
diff changeset
803 int w, m, digits, nsign, nzero, nblank;
kono
parents:
diff changeset
804 char *p;
kono
parents:
diff changeset
805 const char *q;
kono
parents:
diff changeset
806 sign_t sign;
kono
parents:
diff changeset
807 char itoa_buf[GFC_BTOA_BUF_SIZE];
kono
parents:
diff changeset
808
kono
parents:
diff changeset
809 w = f->u.integer.w;
kono
parents:
diff changeset
810 m = f->format == FMT_G ? -1 : f->u.integer.m;
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 n = extract_int (source, len);
kono
parents:
diff changeset
813
kono
parents:
diff changeset
814 /* Special case: */
kono
parents:
diff changeset
815 if (m == 0 && n == 0)
kono
parents:
diff changeset
816 {
kono
parents:
diff changeset
817 if (w == 0)
kono
parents:
diff changeset
818 w = 1;
kono
parents:
diff changeset
819
kono
parents:
diff changeset
820 p = write_block (dtp, w);
kono
parents:
diff changeset
821 if (p == NULL)
kono
parents:
diff changeset
822 return;
kono
parents:
diff changeset
823 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
824 {
kono
parents:
diff changeset
825 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
826 memset4 (p4, ' ', w);
kono
parents:
diff changeset
827 }
kono
parents:
diff changeset
828 else
kono
parents:
diff changeset
829 memset (p, ' ', w);
kono
parents:
diff changeset
830 goto done;
kono
parents:
diff changeset
831 }
kono
parents:
diff changeset
832
kono
parents:
diff changeset
833 sign = calculate_sign (dtp, n < 0);
kono
parents:
diff changeset
834 if (n < 0)
kono
parents:
diff changeset
835 n = -n;
kono
parents:
diff changeset
836 nsign = sign == S_NONE ? 0 : 1;
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 /* conv calls itoa which sets the negative sign needed
kono
parents:
diff changeset
839 by write_integer. The sign '+' or '-' is set below based on sign
kono
parents:
diff changeset
840 calculated above, so we just point past the sign in the string
kono
parents:
diff changeset
841 before proceeding to avoid double signs in corner cases.
kono
parents:
diff changeset
842 (see PR38504) */
kono
parents:
diff changeset
843 q = conv (n, itoa_buf, sizeof (itoa_buf));
kono
parents:
diff changeset
844 if (*q == '-')
kono
parents:
diff changeset
845 q++;
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 digits = strlen (q);
kono
parents:
diff changeset
848
kono
parents:
diff changeset
849 /* Select a width if none was specified. The idea here is to always
kono
parents:
diff changeset
850 print something. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
851 if (w == DEFAULT_WIDTH)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
852 w = default_width_for_integer (len);
111
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 if (w == 0)
kono
parents:
diff changeset
855 w = ((digits < m) ? m : digits) + nsign;
kono
parents:
diff changeset
856
kono
parents:
diff changeset
857 p = write_block (dtp, w);
kono
parents:
diff changeset
858 if (p == NULL)
kono
parents:
diff changeset
859 return;
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 nzero = 0;
kono
parents:
diff changeset
862 if (digits < m)
kono
parents:
diff changeset
863 nzero = m - digits;
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 /* See if things will work. */
kono
parents:
diff changeset
866
kono
parents:
diff changeset
867 nblank = w - (nsign + nzero + digits);
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
870 {
kono
parents:
diff changeset
871 gfc_char4_t *p4 = (gfc_char4_t *)p;
kono
parents:
diff changeset
872 if (nblank < 0)
kono
parents:
diff changeset
873 {
kono
parents:
diff changeset
874 memset4 (p4, '*', w);
kono
parents:
diff changeset
875 goto done;
kono
parents:
diff changeset
876 }
kono
parents:
diff changeset
877
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 if (!dtp->u.p.namelist_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880 memset4 (p4, ' ', nblank);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
881 p4 += nblank;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 }
111
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 switch (sign)
kono
parents:
diff changeset
885 {
kono
parents:
diff changeset
886 case S_PLUS:
kono
parents:
diff changeset
887 *p4++ = '+';
kono
parents:
diff changeset
888 break;
kono
parents:
diff changeset
889 case S_MINUS:
kono
parents:
diff changeset
890 *p4++ = '-';
kono
parents:
diff changeset
891 break;
kono
parents:
diff changeset
892 case S_NONE:
kono
parents:
diff changeset
893 break;
kono
parents:
diff changeset
894 }
kono
parents:
diff changeset
895
kono
parents:
diff changeset
896 memset4 (p4, '0', nzero);
kono
parents:
diff changeset
897 p4 += nzero;
kono
parents:
diff changeset
898
kono
parents:
diff changeset
899 memcpy4 (p4, q, digits);
kono
parents:
diff changeset
900 return;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902 if (dtp->u.p.namelist_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
904 p4 += digits;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
905 memset4 (p4, ' ', nblank);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
906 }
111
kono
parents:
diff changeset
907 }
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 if (nblank < 0)
kono
parents:
diff changeset
910 {
kono
parents:
diff changeset
911 star_fill (p, w);
kono
parents:
diff changeset
912 goto done;
kono
parents:
diff changeset
913 }
kono
parents:
diff changeset
914
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
915 if (!dtp->u.p.namelist_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
916 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 memset (p, ' ', nblank);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
918 p += nblank;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 }
111
kono
parents:
diff changeset
920
kono
parents:
diff changeset
921 switch (sign)
kono
parents:
diff changeset
922 {
kono
parents:
diff changeset
923 case S_PLUS:
kono
parents:
diff changeset
924 *p++ = '+';
kono
parents:
diff changeset
925 break;
kono
parents:
diff changeset
926 case S_MINUS:
kono
parents:
diff changeset
927 *p++ = '-';
kono
parents:
diff changeset
928 break;
kono
parents:
diff changeset
929 case S_NONE:
kono
parents:
diff changeset
930 break;
kono
parents:
diff changeset
931 }
kono
parents:
diff changeset
932
kono
parents:
diff changeset
933 memset (p, '0', nzero);
kono
parents:
diff changeset
934 p += nzero;
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 memcpy (p, q, digits);
kono
parents:
diff changeset
937
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 if (dtp->u.p.namelist_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 p += digits;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 memset (p, ' ', nblank);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943
111
kono
parents:
diff changeset
944 done:
kono
parents:
diff changeset
945 return;
kono
parents:
diff changeset
946 }
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 /* Convert unsigned octal to ascii. */
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951 static const char *
kono
parents:
diff changeset
952 otoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
kono
parents:
diff changeset
953 {
kono
parents:
diff changeset
954 char *p;
kono
parents:
diff changeset
955
kono
parents:
diff changeset
956 assert (len >= GFC_OTOA_BUF_SIZE);
kono
parents:
diff changeset
957
kono
parents:
diff changeset
958 if (n == 0)
kono
parents:
diff changeset
959 return "0";
kono
parents:
diff changeset
960
kono
parents:
diff changeset
961 p = buffer + GFC_OTOA_BUF_SIZE - 1;
kono
parents:
diff changeset
962 *p = '\0';
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 while (n != 0)
kono
parents:
diff changeset
965 {
kono
parents:
diff changeset
966 *--p = '0' + (n & 7);
kono
parents:
diff changeset
967 n >>= 3;
kono
parents:
diff changeset
968 }
kono
parents:
diff changeset
969
kono
parents:
diff changeset
970 return p;
kono
parents:
diff changeset
971 }
kono
parents:
diff changeset
972
kono
parents:
diff changeset
973
kono
parents:
diff changeset
974 /* Convert unsigned binary to ascii. */
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 static const char *
kono
parents:
diff changeset
977 btoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
kono
parents:
diff changeset
978 {
kono
parents:
diff changeset
979 char *p;
kono
parents:
diff changeset
980
kono
parents:
diff changeset
981 assert (len >= GFC_BTOA_BUF_SIZE);
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 if (n == 0)
kono
parents:
diff changeset
984 return "0";
kono
parents:
diff changeset
985
kono
parents:
diff changeset
986 p = buffer + GFC_BTOA_BUF_SIZE - 1;
kono
parents:
diff changeset
987 *p = '\0';
kono
parents:
diff changeset
988
kono
parents:
diff changeset
989 while (n != 0)
kono
parents:
diff changeset
990 {
kono
parents:
diff changeset
991 *--p = '0' + (n & 1);
kono
parents:
diff changeset
992 n >>= 1;
kono
parents:
diff changeset
993 }
kono
parents:
diff changeset
994
kono
parents:
diff changeset
995 return p;
kono
parents:
diff changeset
996 }
kono
parents:
diff changeset
997
kono
parents:
diff changeset
998 /* The following three functions, btoa_big, otoa_big, and ztoa_big, are needed
kono
parents:
diff changeset
999 to convert large reals with kind sizes that exceed the largest integer type
kono
parents:
diff changeset
1000 available on certain platforms. In these cases, byte by byte conversion is
kono
parents:
diff changeset
1001 performed. Endianess is taken into account. */
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 /* Conversion to binary. */
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 static const char *
kono
parents:
diff changeset
1006 btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
kono
parents:
diff changeset
1007 {
kono
parents:
diff changeset
1008 char *q;
kono
parents:
diff changeset
1009 int i, j;
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 q = buffer;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1012 if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
111
kono
parents:
diff changeset
1013 {
kono
parents:
diff changeset
1014 const char *p = s;
kono
parents:
diff changeset
1015 for (i = 0; i < len; i++)
kono
parents:
diff changeset
1016 {
kono
parents:
diff changeset
1017 char c = *p;
kono
parents:
diff changeset
1018
kono
parents:
diff changeset
1019 /* Test for zero. Needed by write_boz later. */
kono
parents:
diff changeset
1020 if (*p != 0)
kono
parents:
diff changeset
1021 *n = 1;
kono
parents:
diff changeset
1022
kono
parents:
diff changeset
1023 for (j = 0; j < 8; j++)
kono
parents:
diff changeset
1024 {
kono
parents:
diff changeset
1025 *q++ = (c & 128) ? '1' : '0';
kono
parents:
diff changeset
1026 c <<= 1;
kono
parents:
diff changeset
1027 }
kono
parents:
diff changeset
1028 p++;
kono
parents:
diff changeset
1029 }
kono
parents:
diff changeset
1030 }
kono
parents:
diff changeset
1031 else
kono
parents:
diff changeset
1032 {
kono
parents:
diff changeset
1033 const char *p = s + len - 1;
kono
parents:
diff changeset
1034 for (i = 0; i < len; i++)
kono
parents:
diff changeset
1035 {
kono
parents:
diff changeset
1036 char c = *p;
kono
parents:
diff changeset
1037
kono
parents:
diff changeset
1038 /* Test for zero. Needed by write_boz later. */
kono
parents:
diff changeset
1039 if (*p != 0)
kono
parents:
diff changeset
1040 *n = 1;
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 for (j = 0; j < 8; j++)
kono
parents:
diff changeset
1043 {
kono
parents:
diff changeset
1044 *q++ = (c & 128) ? '1' : '0';
kono
parents:
diff changeset
1045 c <<= 1;
kono
parents:
diff changeset
1046 }
kono
parents:
diff changeset
1047 p--;
kono
parents:
diff changeset
1048 }
kono
parents:
diff changeset
1049 }
kono
parents:
diff changeset
1050
kono
parents:
diff changeset
1051 if (*n == 0)
kono
parents:
diff changeset
1052 return "0";
kono
parents:
diff changeset
1053
kono
parents:
diff changeset
1054 /* Move past any leading zeros. */
kono
parents:
diff changeset
1055 while (*buffer == '0')
kono
parents:
diff changeset
1056 buffer++;
kono
parents:
diff changeset
1057
kono
parents:
diff changeset
1058 return buffer;
kono
parents:
diff changeset
1059
kono
parents:
diff changeset
1060 }
kono
parents:
diff changeset
1061
kono
parents:
diff changeset
1062 /* Conversion to octal. */
kono
parents:
diff changeset
1063
kono
parents:
diff changeset
1064 static const char *
kono
parents:
diff changeset
1065 otoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
kono
parents:
diff changeset
1066 {
kono
parents:
diff changeset
1067 char *q;
kono
parents:
diff changeset
1068 int i, j, k;
kono
parents:
diff changeset
1069 uint8_t octet;
kono
parents:
diff changeset
1070
kono
parents:
diff changeset
1071 q = buffer + GFC_OTOA_BUF_SIZE - 1;
kono
parents:
diff changeset
1072 *q = '\0';
kono
parents:
diff changeset
1073 i = k = octet = 0;
kono
parents:
diff changeset
1074
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1075 if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
111
kono
parents:
diff changeset
1076 {
kono
parents:
diff changeset
1077 const char *p = s + len - 1;
kono
parents:
diff changeset
1078 char c = *p;
kono
parents:
diff changeset
1079 while (i < len)
kono
parents:
diff changeset
1080 {
kono
parents:
diff changeset
1081 /* Test for zero. Needed by write_boz later. */
kono
parents:
diff changeset
1082 if (*p != 0)
kono
parents:
diff changeset
1083 *n = 1;
kono
parents:
diff changeset
1084
kono
parents:
diff changeset
1085 for (j = 0; j < 3 && i < len; j++)
kono
parents:
diff changeset
1086 {
kono
parents:
diff changeset
1087 octet |= (c & 1) << j;
kono
parents:
diff changeset
1088 c >>= 1;
kono
parents:
diff changeset
1089 if (++k > 7)
kono
parents:
diff changeset
1090 {
kono
parents:
diff changeset
1091 i++;
kono
parents:
diff changeset
1092 k = 0;
kono
parents:
diff changeset
1093 c = *--p;
kono
parents:
diff changeset
1094 }
kono
parents:
diff changeset
1095 }
kono
parents:
diff changeset
1096 *--q = '0' + octet;
kono
parents:
diff changeset
1097 octet = 0;
kono
parents:
diff changeset
1098 }
kono
parents:
diff changeset
1099 }
kono
parents:
diff changeset
1100 else
kono
parents:
diff changeset
1101 {
kono
parents:
diff changeset
1102 const char *p = s;
kono
parents:
diff changeset
1103 char c = *p;
kono
parents:
diff changeset
1104 while (i < len)
kono
parents:
diff changeset
1105 {
kono
parents:
diff changeset
1106 /* Test for zero. Needed by write_boz later. */
kono
parents:
diff changeset
1107 if (*p != 0)
kono
parents:
diff changeset
1108 *n = 1;
kono
parents:
diff changeset
1109
kono
parents:
diff changeset
1110 for (j = 0; j < 3 && i < len; j++)
kono
parents:
diff changeset
1111 {
kono
parents:
diff changeset
1112 octet |= (c & 1) << j;
kono
parents:
diff changeset
1113 c >>= 1;
kono
parents:
diff changeset
1114 if (++k > 7)
kono
parents:
diff changeset
1115 {
kono
parents:
diff changeset
1116 i++;
kono
parents:
diff changeset
1117 k = 0;
kono
parents:
diff changeset
1118 c = *++p;
kono
parents:
diff changeset
1119 }
kono
parents:
diff changeset
1120 }
kono
parents:
diff changeset
1121 *--q = '0' + octet;
kono
parents:
diff changeset
1122 octet = 0;
kono
parents:
diff changeset
1123 }
kono
parents:
diff changeset
1124 }
kono
parents:
diff changeset
1125
kono
parents:
diff changeset
1126 if (*n == 0)
kono
parents:
diff changeset
1127 return "0";
kono
parents:
diff changeset
1128
kono
parents:
diff changeset
1129 /* Move past any leading zeros. */
kono
parents:
diff changeset
1130 while (*q == '0')
kono
parents:
diff changeset
1131 q++;
kono
parents:
diff changeset
1132
kono
parents:
diff changeset
1133 return q;
kono
parents:
diff changeset
1134 }
kono
parents:
diff changeset
1135
kono
parents:
diff changeset
1136 /* Conversion to hexidecimal. */
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 static const char *
kono
parents:
diff changeset
1139 ztoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
kono
parents:
diff changeset
1140 {
kono
parents:
diff changeset
1141 static char a[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
kono
parents:
diff changeset
1142 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
kono
parents:
diff changeset
1143
kono
parents:
diff changeset
1144 char *q;
kono
parents:
diff changeset
1145 uint8_t h, l;
kono
parents:
diff changeset
1146 int i;
kono
parents:
diff changeset
1147
kono
parents:
diff changeset
1148 q = buffer;
kono
parents:
diff changeset
1149
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1150 if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
111
kono
parents:
diff changeset
1151 {
kono
parents:
diff changeset
1152 const char *p = s;
kono
parents:
diff changeset
1153 for (i = 0; i < len; i++)
kono
parents:
diff changeset
1154 {
kono
parents:
diff changeset
1155 /* Test for zero. Needed by write_boz later. */
kono
parents:
diff changeset
1156 if (*p != 0)
kono
parents:
diff changeset
1157 *n = 1;
kono
parents:
diff changeset
1158
kono
parents:
diff changeset
1159 h = (*p >> 4) & 0x0F;
kono
parents:
diff changeset
1160 l = *p++ & 0x0F;
kono
parents:
diff changeset
1161 *q++ = a[h];
kono
parents:
diff changeset
1162 *q++ = a[l];
kono
parents:
diff changeset
1163 }
kono
parents:
diff changeset
1164 }
kono
parents:
diff changeset
1165 else
kono
parents:
diff changeset
1166 {
kono
parents:
diff changeset
1167 const char *p = s + len - 1;
kono
parents:
diff changeset
1168 for (i = 0; i < len; i++)
kono
parents:
diff changeset
1169 {
kono
parents:
diff changeset
1170 /* Test for zero. Needed by write_boz later. */
kono
parents:
diff changeset
1171 if (*p != 0)
kono
parents:
diff changeset
1172 *n = 1;
kono
parents:
diff changeset
1173
kono
parents:
diff changeset
1174 h = (*p >> 4) & 0x0F;
kono
parents:
diff changeset
1175 l = *p-- & 0x0F;
kono
parents:
diff changeset
1176 *q++ = a[h];
kono
parents:
diff changeset
1177 *q++ = a[l];
kono
parents:
diff changeset
1178 }
kono
parents:
diff changeset
1179 }
kono
parents:
diff changeset
1180
kono
parents:
diff changeset
1181 *q = '\0';
kono
parents:
diff changeset
1182
kono
parents:
diff changeset
1183 if (*n == 0)
kono
parents:
diff changeset
1184 return "0";
kono
parents:
diff changeset
1185
kono
parents:
diff changeset
1186 /* Move past any leading zeros. */
kono
parents:
diff changeset
1187 while (*buffer == '0')
kono
parents:
diff changeset
1188 buffer++;
kono
parents:
diff changeset
1189
kono
parents:
diff changeset
1190 return buffer;
kono
parents:
diff changeset
1191 }
kono
parents:
diff changeset
1192
kono
parents:
diff changeset
1193
kono
parents:
diff changeset
1194 void
kono
parents:
diff changeset
1195 write_i (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
kono
parents:
diff changeset
1196 {
kono
parents:
diff changeset
1197 write_decimal (dtp, f, p, len, (void *) gfc_itoa);
kono
parents:
diff changeset
1198 }
kono
parents:
diff changeset
1199
kono
parents:
diff changeset
1200
kono
parents:
diff changeset
1201 void
kono
parents:
diff changeset
1202 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
kono
parents:
diff changeset
1203 {
kono
parents:
diff changeset
1204 const char *p;
kono
parents:
diff changeset
1205 char itoa_buf[GFC_BTOA_BUF_SIZE];
kono
parents:
diff changeset
1206 GFC_UINTEGER_LARGEST n = 0;
kono
parents:
diff changeset
1207
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1208 /* Ensure we end up with a null terminated string. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1209 memset(itoa_buf, '\0', GFC_BTOA_BUF_SIZE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1210
111
kono
parents:
diff changeset
1211 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
kono
parents:
diff changeset
1212 {
kono
parents:
diff changeset
1213 p = btoa_big (source, itoa_buf, len, &n);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1214 write_boz (dtp, f, p, n, len);
111
kono
parents:
diff changeset
1215 }
kono
parents:
diff changeset
1216 else
kono
parents:
diff changeset
1217 {
kono
parents:
diff changeset
1218 n = extract_uint (source, len);
kono
parents:
diff changeset
1219 p = btoa (n, itoa_buf, sizeof (itoa_buf));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1220 write_boz (dtp, f, p, n, len);
111
kono
parents:
diff changeset
1221 }
kono
parents:
diff changeset
1222 }
kono
parents:
diff changeset
1223
kono
parents:
diff changeset
1224
kono
parents:
diff changeset
1225 void
kono
parents:
diff changeset
1226 write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
kono
parents:
diff changeset
1227 {
kono
parents:
diff changeset
1228 const char *p;
kono
parents:
diff changeset
1229 char itoa_buf[GFC_OTOA_BUF_SIZE];
kono
parents:
diff changeset
1230 GFC_UINTEGER_LARGEST n = 0;
kono
parents:
diff changeset
1231
kono
parents:
diff changeset
1232 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
kono
parents:
diff changeset
1233 {
kono
parents:
diff changeset
1234 p = otoa_big (source, itoa_buf, len, &n);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1235 write_boz (dtp, f, p, n, len);
111
kono
parents:
diff changeset
1236 }
kono
parents:
diff changeset
1237 else
kono
parents:
diff changeset
1238 {
kono
parents:
diff changeset
1239 n = extract_uint (source, len);
kono
parents:
diff changeset
1240 p = otoa (n, itoa_buf, sizeof (itoa_buf));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1241 write_boz (dtp, f, p, n, len);
111
kono
parents:
diff changeset
1242 }
kono
parents:
diff changeset
1243 }
kono
parents:
diff changeset
1244
kono
parents:
diff changeset
1245 void
kono
parents:
diff changeset
1246 write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
kono
parents:
diff changeset
1247 {
kono
parents:
diff changeset
1248 const char *p;
kono
parents:
diff changeset
1249 char itoa_buf[GFC_XTOA_BUF_SIZE];
kono
parents:
diff changeset
1250 GFC_UINTEGER_LARGEST n = 0;
kono
parents:
diff changeset
1251
kono
parents:
diff changeset
1252 if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
kono
parents:
diff changeset
1253 {
kono
parents:
diff changeset
1254 p = ztoa_big (source, itoa_buf, len, &n);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1255 write_boz (dtp, f, p, n, len);
111
kono
parents:
diff changeset
1256 }
kono
parents:
diff changeset
1257 else
kono
parents:
diff changeset
1258 {
kono
parents:
diff changeset
1259 n = extract_uint (source, len);
kono
parents:
diff changeset
1260 p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1261 write_boz (dtp, f, p, n, len);
111
kono
parents:
diff changeset
1262 }
kono
parents:
diff changeset
1263 }
kono
parents:
diff changeset
1264
kono
parents:
diff changeset
1265 /* Take care of the X/TR descriptor. */
kono
parents:
diff changeset
1266
kono
parents:
diff changeset
1267 void
kono
parents:
diff changeset
1268 write_x (st_parameter_dt *dtp, int len, int nspaces)
kono
parents:
diff changeset
1269 {
kono
parents:
diff changeset
1270 char *p;
kono
parents:
diff changeset
1271
kono
parents:
diff changeset
1272 p = write_block (dtp, len);
kono
parents:
diff changeset
1273 if (p == NULL)
kono
parents:
diff changeset
1274 return;
kono
parents:
diff changeset
1275 if (nspaces > 0 && len - nspaces >= 0)
kono
parents:
diff changeset
1276 {
kono
parents:
diff changeset
1277 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
1278 {
kono
parents:
diff changeset
1279 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
1280 memset4 (&p4[len - nspaces], ' ', nspaces);
kono
parents:
diff changeset
1281 }
kono
parents:
diff changeset
1282 else
kono
parents:
diff changeset
1283 memset (&p[len - nspaces], ' ', nspaces);
kono
parents:
diff changeset
1284 }
kono
parents:
diff changeset
1285 }
kono
parents:
diff changeset
1286
kono
parents:
diff changeset
1287
kono
parents:
diff changeset
1288 /* List-directed writing. */
kono
parents:
diff changeset
1289
kono
parents:
diff changeset
1290
kono
parents:
diff changeset
1291 /* Write a single character to the output. Returns nonzero if
kono
parents:
diff changeset
1292 something goes wrong. */
kono
parents:
diff changeset
1293
kono
parents:
diff changeset
1294 static int
kono
parents:
diff changeset
1295 write_char (st_parameter_dt *dtp, int c)
kono
parents:
diff changeset
1296 {
kono
parents:
diff changeset
1297 char *p;
kono
parents:
diff changeset
1298
kono
parents:
diff changeset
1299 p = write_block (dtp, 1);
kono
parents:
diff changeset
1300 if (p == NULL)
kono
parents:
diff changeset
1301 return 1;
kono
parents:
diff changeset
1302 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
1303 {
kono
parents:
diff changeset
1304 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
1305 *p4 = c;
kono
parents:
diff changeset
1306 return 0;
kono
parents:
diff changeset
1307 }
kono
parents:
diff changeset
1308
kono
parents:
diff changeset
1309 *p = (uchar) c;
kono
parents:
diff changeset
1310
kono
parents:
diff changeset
1311 return 0;
kono
parents:
diff changeset
1312 }
kono
parents:
diff changeset
1313
kono
parents:
diff changeset
1314
kono
parents:
diff changeset
1315 /* Write a list-directed logical value. */
kono
parents:
diff changeset
1316
kono
parents:
diff changeset
1317 static void
kono
parents:
diff changeset
1318 write_logical (st_parameter_dt *dtp, const char *source, int length)
kono
parents:
diff changeset
1319 {
kono
parents:
diff changeset
1320 write_char (dtp, extract_int (source, length) ? 'T' : 'F');
kono
parents:
diff changeset
1321 }
kono
parents:
diff changeset
1322
kono
parents:
diff changeset
1323
kono
parents:
diff changeset
1324 /* Write a list-directed integer value. */
kono
parents:
diff changeset
1325
kono
parents:
diff changeset
1326 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1327 write_integer (st_parameter_dt *dtp, const char *source, int kind)
111
kono
parents:
diff changeset
1328 {
kono
parents:
diff changeset
1329 int width;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1330 fnode f;
111
kono
parents:
diff changeset
1331
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1332 switch (kind)
111
kono
parents:
diff changeset
1333 {
kono
parents:
diff changeset
1334 case 1:
kono
parents:
diff changeset
1335 width = 4;
kono
parents:
diff changeset
1336 break;
kono
parents:
diff changeset
1337
kono
parents:
diff changeset
1338 case 2:
kono
parents:
diff changeset
1339 width = 6;
kono
parents:
diff changeset
1340 break;
kono
parents:
diff changeset
1341
kono
parents:
diff changeset
1342 case 4:
kono
parents:
diff changeset
1343 width = 11;
kono
parents:
diff changeset
1344 break;
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 case 8:
kono
parents:
diff changeset
1347 width = 20;
kono
parents:
diff changeset
1348 break;
kono
parents:
diff changeset
1349
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1350 case 16:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1351 width = 40;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1352 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1353
111
kono
parents:
diff changeset
1354 default:
kono
parents:
diff changeset
1355 width = 0;
kono
parents:
diff changeset
1356 break;
kono
parents:
diff changeset
1357 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1358 f.u.integer.w = width;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1359 f.u.integer.m = -1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1360 f.format = FMT_NONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1361 write_decimal (dtp, &f, source, kind, (void *) gfc_itoa);
111
kono
parents:
diff changeset
1362 }
kono
parents:
diff changeset
1363
kono
parents:
diff changeset
1364
kono
parents:
diff changeset
1365 /* Write a list-directed string. We have to worry about delimiting
kono
parents:
diff changeset
1366 the strings if the file has been opened in that mode. */
kono
parents:
diff changeset
1367
kono
parents:
diff changeset
1368 #define DELIM 1
kono
parents:
diff changeset
1369 #define NODELIM 0
kono
parents:
diff changeset
1370
kono
parents:
diff changeset
1371 static void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1372 write_character (st_parameter_dt *dtp, const char *source, int kind, size_t length, int mode)
111
kono
parents:
diff changeset
1373 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1374 size_t extra;
111
kono
parents:
diff changeset
1375 char *p, d;
kono
parents:
diff changeset
1376
kono
parents:
diff changeset
1377 if (mode == DELIM)
kono
parents:
diff changeset
1378 {
kono
parents:
diff changeset
1379 switch (dtp->u.p.current_unit->delim_status)
kono
parents:
diff changeset
1380 {
kono
parents:
diff changeset
1381 case DELIM_APOSTROPHE:
kono
parents:
diff changeset
1382 d = '\'';
kono
parents:
diff changeset
1383 break;
kono
parents:
diff changeset
1384 case DELIM_QUOTE:
kono
parents:
diff changeset
1385 d = '"';
kono
parents:
diff changeset
1386 break;
kono
parents:
diff changeset
1387 default:
kono
parents:
diff changeset
1388 d = ' ';
kono
parents:
diff changeset
1389 break;
kono
parents:
diff changeset
1390 }
kono
parents:
diff changeset
1391 }
kono
parents:
diff changeset
1392 else
kono
parents:
diff changeset
1393 d = ' ';
kono
parents:
diff changeset
1394
kono
parents:
diff changeset
1395 if (kind == 1)
kono
parents:
diff changeset
1396 {
kono
parents:
diff changeset
1397 if (d == ' ')
kono
parents:
diff changeset
1398 extra = 0;
kono
parents:
diff changeset
1399 else
kono
parents:
diff changeset
1400 {
kono
parents:
diff changeset
1401 extra = 2;
kono
parents:
diff changeset
1402
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1403 for (size_t i = 0; i < length; i++)
111
kono
parents:
diff changeset
1404 if (source[i] == d)
kono
parents:
diff changeset
1405 extra++;
kono
parents:
diff changeset
1406 }
kono
parents:
diff changeset
1407
kono
parents:
diff changeset
1408 p = write_block (dtp, length + extra);
kono
parents:
diff changeset
1409 if (p == NULL)
kono
parents:
diff changeset
1410 return;
kono
parents:
diff changeset
1411
kono
parents:
diff changeset
1412 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
1413 {
kono
parents:
diff changeset
1414 gfc_char4_t d4 = (gfc_char4_t) d;
kono
parents:
diff changeset
1415 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
1416
kono
parents:
diff changeset
1417 if (d4 == ' ')
kono
parents:
diff changeset
1418 memcpy4 (p4, source, length);
kono
parents:
diff changeset
1419 else
kono
parents:
diff changeset
1420 {
kono
parents:
diff changeset
1421 *p4++ = d4;
kono
parents:
diff changeset
1422
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1423 for (size_t i = 0; i < length; i++)
111
kono
parents:
diff changeset
1424 {
kono
parents:
diff changeset
1425 *p4++ = (gfc_char4_t) source[i];
kono
parents:
diff changeset
1426 if (source[i] == d)
kono
parents:
diff changeset
1427 *p4++ = d4;
kono
parents:
diff changeset
1428 }
kono
parents:
diff changeset
1429
kono
parents:
diff changeset
1430 *p4 = d4;
kono
parents:
diff changeset
1431 }
kono
parents:
diff changeset
1432 return;
kono
parents:
diff changeset
1433 }
kono
parents:
diff changeset
1434
kono
parents:
diff changeset
1435 if (d == ' ')
kono
parents:
diff changeset
1436 memcpy (p, source, length);
kono
parents:
diff changeset
1437 else
kono
parents:
diff changeset
1438 {
kono
parents:
diff changeset
1439 *p++ = d;
kono
parents:
diff changeset
1440
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1441 for (size_t i = 0; i < length; i++)
111
kono
parents:
diff changeset
1442 {
kono
parents:
diff changeset
1443 *p++ = source[i];
kono
parents:
diff changeset
1444 if (source[i] == d)
kono
parents:
diff changeset
1445 *p++ = d;
kono
parents:
diff changeset
1446 }
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 *p = d;
kono
parents:
diff changeset
1449 }
kono
parents:
diff changeset
1450 }
kono
parents:
diff changeset
1451 else
kono
parents:
diff changeset
1452 {
kono
parents:
diff changeset
1453 if (d == ' ')
kono
parents:
diff changeset
1454 {
kono
parents:
diff changeset
1455 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
kono
parents:
diff changeset
1456 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
kono
parents:
diff changeset
1457 else
kono
parents:
diff changeset
1458 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
kono
parents:
diff changeset
1459 }
kono
parents:
diff changeset
1460 else
kono
parents:
diff changeset
1461 {
kono
parents:
diff changeset
1462 p = write_block (dtp, 1);
kono
parents:
diff changeset
1463 *p = d;
kono
parents:
diff changeset
1464
kono
parents:
diff changeset
1465 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
kono
parents:
diff changeset
1466 write_utf8_char4 (dtp, (gfc_char4_t *) source, length, 0);
kono
parents:
diff changeset
1467 else
kono
parents:
diff changeset
1468 write_default_char4 (dtp, (gfc_char4_t *) source, length, 0);
kono
parents:
diff changeset
1469
kono
parents:
diff changeset
1470 p = write_block (dtp, 1);
kono
parents:
diff changeset
1471 *p = d;
kono
parents:
diff changeset
1472 }
kono
parents:
diff changeset
1473 }
kono
parents:
diff changeset
1474 }
kono
parents:
diff changeset
1475
kono
parents:
diff changeset
1476 /* Floating point helper functions. */
kono
parents:
diff changeset
1477
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1478 #define BUF_STACK_SZ 384
111
kono
parents:
diff changeset
1479
kono
parents:
diff changeset
1480 static int
kono
parents:
diff changeset
1481 get_precision (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
kono
parents:
diff changeset
1482 {
kono
parents:
diff changeset
1483 if (f->format != FMT_EN)
kono
parents:
diff changeset
1484 return determine_precision (dtp, f, kind);
kono
parents:
diff changeset
1485 else
kono
parents:
diff changeset
1486 return determine_en_precision (dtp, f, source, kind);
kono
parents:
diff changeset
1487 }
kono
parents:
diff changeset
1488
kono
parents:
diff changeset
1489 /* 4932 is the maximum exponent of long double and quad precision, 3
kono
parents:
diff changeset
1490 extra characters for the sign, the decimal point, and the
kono
parents:
diff changeset
1491 trailing null. Extra digits are added by the calling functions for
kono
parents:
diff changeset
1492 requested precision. Likewise for float and double. F0 editing produces
kono
parents:
diff changeset
1493 full precision output. */
kono
parents:
diff changeset
1494 static int
kono
parents:
diff changeset
1495 size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
kono
parents:
diff changeset
1496 {
kono
parents:
diff changeset
1497 int size;
kono
parents:
diff changeset
1498
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1499 if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH)
111
kono
parents:
diff changeset
1500 {
kono
parents:
diff changeset
1501 switch (kind)
kono
parents:
diff changeset
1502 {
kono
parents:
diff changeset
1503 case 4:
kono
parents:
diff changeset
1504 size = 38 + 3; /* These constants shown for clarity. */
kono
parents:
diff changeset
1505 break;
kono
parents:
diff changeset
1506 case 8:
kono
parents:
diff changeset
1507 size = 308 + 3;
kono
parents:
diff changeset
1508 break;
kono
parents:
diff changeset
1509 case 10:
kono
parents:
diff changeset
1510 size = 4932 + 3;
kono
parents:
diff changeset
1511 break;
kono
parents:
diff changeset
1512 case 16:
kono
parents:
diff changeset
1513 size = 4932 + 3;
kono
parents:
diff changeset
1514 break;
kono
parents:
diff changeset
1515 default:
kono
parents:
diff changeset
1516 internal_error (&dtp->common, "bad real kind");
kono
parents:
diff changeset
1517 break;
kono
parents:
diff changeset
1518 }
kono
parents:
diff changeset
1519 }
kono
parents:
diff changeset
1520 else
kono
parents:
diff changeset
1521 size = f->u.real.w + 1; /* One byte for a NULL character. */
kono
parents:
diff changeset
1522
kono
parents:
diff changeset
1523 return size;
kono
parents:
diff changeset
1524 }
kono
parents:
diff changeset
1525
kono
parents:
diff changeset
1526 static char *
kono
parents:
diff changeset
1527 select_buffer (st_parameter_dt *dtp, const fnode *f, int precision,
kono
parents:
diff changeset
1528 char *buf, size_t *size, int kind)
kono
parents:
diff changeset
1529 {
kono
parents:
diff changeset
1530 char *result;
kono
parents:
diff changeset
1531
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1532 /* The buffer needs at least one more byte to allow room for
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1533 normalizing and 1 to hold null terminator. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1534 *size = size_from_kind (dtp, f, kind) + precision + 1 + 1;
111
kono
parents:
diff changeset
1535
kono
parents:
diff changeset
1536 if (*size > BUF_STACK_SZ)
kono
parents:
diff changeset
1537 result = xmalloc (*size);
kono
parents:
diff changeset
1538 else
kono
parents:
diff changeset
1539 result = buf;
kono
parents:
diff changeset
1540 return result;
kono
parents:
diff changeset
1541 }
kono
parents:
diff changeset
1542
kono
parents:
diff changeset
1543 static char *
kono
parents:
diff changeset
1544 select_string (st_parameter_dt *dtp, const fnode *f, char *buf, size_t *size,
kono
parents:
diff changeset
1545 int kind)
kono
parents:
diff changeset
1546 {
kono
parents:
diff changeset
1547 char *result;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1548 *size = size_from_kind (dtp, f, kind) + f->u.real.d + 1;
111
kono
parents:
diff changeset
1549 if (*size > BUF_STACK_SZ)
kono
parents:
diff changeset
1550 result = xmalloc (*size);
kono
parents:
diff changeset
1551 else
kono
parents:
diff changeset
1552 result = buf;
kono
parents:
diff changeset
1553 return result;
kono
parents:
diff changeset
1554 }
kono
parents:
diff changeset
1555
kono
parents:
diff changeset
1556 static void
kono
parents:
diff changeset
1557 write_float_string (st_parameter_dt *dtp, char *fstr, size_t len)
kono
parents:
diff changeset
1558 {
kono
parents:
diff changeset
1559 char *p = write_block (dtp, len);
kono
parents:
diff changeset
1560 if (p == NULL)
kono
parents:
diff changeset
1561 return;
kono
parents:
diff changeset
1562
kono
parents:
diff changeset
1563 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
1564 {
kono
parents:
diff changeset
1565 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
1566 memcpy4 (p4, fstr, len);
kono
parents:
diff changeset
1567 return;
kono
parents:
diff changeset
1568 }
kono
parents:
diff changeset
1569 memcpy (p, fstr, len);
kono
parents:
diff changeset
1570 }
kono
parents:
diff changeset
1571
kono
parents:
diff changeset
1572
kono
parents:
diff changeset
1573 static void
kono
parents:
diff changeset
1574 write_float_0 (st_parameter_dt *dtp, const fnode *f, const char *source, int kind)
kono
parents:
diff changeset
1575 {
kono
parents:
diff changeset
1576 char buf_stack[BUF_STACK_SZ];
kono
parents:
diff changeset
1577 char str_buf[BUF_STACK_SZ];
kono
parents:
diff changeset
1578 char *buffer, *result;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1579 size_t buf_size, res_len, flt_str_len;
111
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 /* Precision for snprintf call. */
kono
parents:
diff changeset
1582 int precision = get_precision (dtp, f, source, kind);
kono
parents:
diff changeset
1583
kono
parents:
diff changeset
1584 /* String buffer to hold final result. */
kono
parents:
diff changeset
1585 result = select_string (dtp, f, str_buf, &res_len, kind);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1586
111
kono
parents:
diff changeset
1587 buffer = select_buffer (dtp, f, precision, buf_stack, &buf_size, kind);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1588
111
kono
parents:
diff changeset
1589 get_float_string (dtp, f, source , kind, 0, buffer,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1590 precision, buf_size, result, &flt_str_len);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1591 write_float_string (dtp, result, flt_str_len);
111
kono
parents:
diff changeset
1592
kono
parents:
diff changeset
1593 if (buf_size > BUF_STACK_SZ)
kono
parents:
diff changeset
1594 free (buffer);
kono
parents:
diff changeset
1595 if (res_len > BUF_STACK_SZ)
kono
parents:
diff changeset
1596 free (result);
kono
parents:
diff changeset
1597 }
kono
parents:
diff changeset
1598
kono
parents:
diff changeset
1599 void
kono
parents:
diff changeset
1600 write_d (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
kono
parents:
diff changeset
1601 {
kono
parents:
diff changeset
1602 write_float_0 (dtp, f, p, len);
kono
parents:
diff changeset
1603 }
kono
parents:
diff changeset
1604
kono
parents:
diff changeset
1605
kono
parents:
diff changeset
1606 void
kono
parents:
diff changeset
1607 write_e (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
kono
parents:
diff changeset
1608 {
kono
parents:
diff changeset
1609 write_float_0 (dtp, f, p, len);
kono
parents:
diff changeset
1610 }
kono
parents:
diff changeset
1611
kono
parents:
diff changeset
1612
kono
parents:
diff changeset
1613 void
kono
parents:
diff changeset
1614 write_f (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
kono
parents:
diff changeset
1615 {
kono
parents:
diff changeset
1616 write_float_0 (dtp, f, p, len);
kono
parents:
diff changeset
1617 }
kono
parents:
diff changeset
1618
kono
parents:
diff changeset
1619
kono
parents:
diff changeset
1620 void
kono
parents:
diff changeset
1621 write_en (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
kono
parents:
diff changeset
1622 {
kono
parents:
diff changeset
1623 write_float_0 (dtp, f, p, len);
kono
parents:
diff changeset
1624 }
kono
parents:
diff changeset
1625
kono
parents:
diff changeset
1626
kono
parents:
diff changeset
1627 void
kono
parents:
diff changeset
1628 write_es (st_parameter_dt *dtp, const fnode *f, const char *p, int len)
kono
parents:
diff changeset
1629 {
kono
parents:
diff changeset
1630 write_float_0 (dtp, f, p, len);
kono
parents:
diff changeset
1631 }
kono
parents:
diff changeset
1632
kono
parents:
diff changeset
1633
kono
parents:
diff changeset
1634 /* Set an fnode to default format. */
kono
parents:
diff changeset
1635
kono
parents:
diff changeset
1636 static void
kono
parents:
diff changeset
1637 set_fnode_default (st_parameter_dt *dtp, fnode *f, int length)
kono
parents:
diff changeset
1638 {
kono
parents:
diff changeset
1639 f->format = FMT_G;
kono
parents:
diff changeset
1640 switch (length)
kono
parents:
diff changeset
1641 {
kono
parents:
diff changeset
1642 case 4:
kono
parents:
diff changeset
1643 f->u.real.w = 16;
kono
parents:
diff changeset
1644 f->u.real.d = 9;
kono
parents:
diff changeset
1645 f->u.real.e = 2;
kono
parents:
diff changeset
1646 break;
kono
parents:
diff changeset
1647 case 8:
kono
parents:
diff changeset
1648 f->u.real.w = 25;
kono
parents:
diff changeset
1649 f->u.real.d = 17;
kono
parents:
diff changeset
1650 f->u.real.e = 3;
kono
parents:
diff changeset
1651 break;
kono
parents:
diff changeset
1652 case 10:
kono
parents:
diff changeset
1653 f->u.real.w = 30;
kono
parents:
diff changeset
1654 f->u.real.d = 21;
kono
parents:
diff changeset
1655 f->u.real.e = 4;
kono
parents:
diff changeset
1656 break;
kono
parents:
diff changeset
1657 case 16:
kono
parents:
diff changeset
1658 /* Adjust decimal precision depending on binary precision, 106 or 113. */
kono
parents:
diff changeset
1659 #if GFC_REAL_16_DIGITS == 113
kono
parents:
diff changeset
1660 f->u.real.w = 45;
kono
parents:
diff changeset
1661 f->u.real.d = 36;
kono
parents:
diff changeset
1662 f->u.real.e = 4;
kono
parents:
diff changeset
1663 #else
kono
parents:
diff changeset
1664 f->u.real.w = 41;
kono
parents:
diff changeset
1665 f->u.real.d = 32;
kono
parents:
diff changeset
1666 f->u.real.e = 4;
kono
parents:
diff changeset
1667 #endif
kono
parents:
diff changeset
1668 break;
kono
parents:
diff changeset
1669 default:
kono
parents:
diff changeset
1670 internal_error (&dtp->common, "bad real kind");
kono
parents:
diff changeset
1671 break;
kono
parents:
diff changeset
1672 }
kono
parents:
diff changeset
1673 }
kono
parents:
diff changeset
1674
kono
parents:
diff changeset
1675 /* Output a real number with default format.
kono
parents:
diff changeset
1676 To guarantee that a binary -> decimal -> binary roundtrip conversion
kono
parents:
diff changeset
1677 recovers the original value, IEEE 754-2008 requires 9, 17, 21 and 36
kono
parents:
diff changeset
1678 significant digits for REAL kinds 4, 8, 10, and 16, respectively.
kono
parents:
diff changeset
1679 Thus, we use 1PG16.9E2 for REAL(4), 1PG25.17E3 for REAL(8), 1PG30.21E4
kono
parents:
diff changeset
1680 for REAL(10) and 1PG45.36E4 for REAL(16). The exception is that the
kono
parents:
diff changeset
1681 Fortran standard requires outputting an extra digit when the scale
kono
parents:
diff changeset
1682 factor is 1 and when the magnitude of the value is such that E
kono
parents:
diff changeset
1683 editing is used. However, gfortran compensates for this, and thus
kono
parents:
diff changeset
1684 for list formatted the same number of significant digits is
kono
parents:
diff changeset
1685 generated both when using F and E editing. */
kono
parents:
diff changeset
1686
kono
parents:
diff changeset
1687 void
kono
parents:
diff changeset
1688 write_real (st_parameter_dt *dtp, const char *source, int kind)
kono
parents:
diff changeset
1689 {
kono
parents:
diff changeset
1690 fnode f ;
kono
parents:
diff changeset
1691 char buf_stack[BUF_STACK_SZ];
kono
parents:
diff changeset
1692 char str_buf[BUF_STACK_SZ];
kono
parents:
diff changeset
1693 char *buffer, *result;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1694 size_t buf_size, res_len, flt_str_len;
111
kono
parents:
diff changeset
1695 int orig_scale = dtp->u.p.scale_factor;
kono
parents:
diff changeset
1696 dtp->u.p.scale_factor = 1;
kono
parents:
diff changeset
1697 set_fnode_default (dtp, &f, kind);
kono
parents:
diff changeset
1698
kono
parents:
diff changeset
1699 /* Precision for snprintf call. */
kono
parents:
diff changeset
1700 int precision = get_precision (dtp, &f, source, kind);
kono
parents:
diff changeset
1701
kono
parents:
diff changeset
1702 /* String buffer to hold final result. */
kono
parents:
diff changeset
1703 result = select_string (dtp, &f, str_buf, &res_len, kind);
kono
parents:
diff changeset
1704
kono
parents:
diff changeset
1705 /* Scratch buffer to hold final result. */
kono
parents:
diff changeset
1706 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
kono
parents:
diff changeset
1707
kono
parents:
diff changeset
1708 get_float_string (dtp, &f, source , kind, 1, buffer,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1709 precision, buf_size, result, &flt_str_len);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1710 write_float_string (dtp, result, flt_str_len);
111
kono
parents:
diff changeset
1711
kono
parents:
diff changeset
1712 dtp->u.p.scale_factor = orig_scale;
kono
parents:
diff changeset
1713 if (buf_size > BUF_STACK_SZ)
kono
parents:
diff changeset
1714 free (buffer);
kono
parents:
diff changeset
1715 if (res_len > BUF_STACK_SZ)
kono
parents:
diff changeset
1716 free (result);
kono
parents:
diff changeset
1717 }
kono
parents:
diff changeset
1718
kono
parents:
diff changeset
1719 /* Similar to list formatted REAL output, for kPG0 where k > 0 we
kono
parents:
diff changeset
1720 compensate for the extra digit. */
kono
parents:
diff changeset
1721
kono
parents:
diff changeset
1722 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1723 write_real_w0 (st_parameter_dt *dtp, const char *source, int kind,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1724 const fnode* f)
111
kono
parents:
diff changeset
1725 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1726 fnode ff;
111
kono
parents:
diff changeset
1727 char buf_stack[BUF_STACK_SZ];
kono
parents:
diff changeset
1728 char str_buf[BUF_STACK_SZ];
kono
parents:
diff changeset
1729 char *buffer, *result;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1730 size_t buf_size, res_len, flt_str_len;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1731 int comp_d = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1732
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1733 set_fnode_default (dtp, &ff, kind);
111
kono
parents:
diff changeset
1734
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1735 if (f->u.real.d > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1736 ff.u.real.d = f->u.real.d;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1737 ff.format = f->format;
111
kono
parents:
diff changeset
1738
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1739 /* For FMT_G, Compensate for extra digits when using scale factor, d
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1740 is not specified, and the magnitude is such that E editing
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1741 is used. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1742 if (f->format == FMT_G)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1743 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1744 if (dtp->u.p.scale_factor > 0 && f->u.real.d == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1745 comp_d = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1746 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1747 comp_d = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1748 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1749
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1750 if (f->u.real.e >= 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1751 ff.u.real.e = f->u.real.e;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1752
111
kono
parents:
diff changeset
1753 dtp->u.p.g0_no_blanks = 1;
kono
parents:
diff changeset
1754
kono
parents:
diff changeset
1755 /* Precision for snprintf call. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1756 int precision = get_precision (dtp, &ff, source, kind);
111
kono
parents:
diff changeset
1757
kono
parents:
diff changeset
1758 /* String buffer to hold final result. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1759 result = select_string (dtp, &ff, str_buf, &res_len, kind);
111
kono
parents:
diff changeset
1760
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1761 buffer = select_buffer (dtp, &ff, precision, buf_stack, &buf_size, kind);
111
kono
parents:
diff changeset
1762
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1763 get_float_string (dtp, &ff, source , kind, comp_d, buffer,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1764 precision, buf_size, result, &flt_str_len);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1765 write_float_string (dtp, result, flt_str_len);
111
kono
parents:
diff changeset
1766
kono
parents:
diff changeset
1767 dtp->u.p.g0_no_blanks = 0;
kono
parents:
diff changeset
1768 if (buf_size > BUF_STACK_SZ)
kono
parents:
diff changeset
1769 free (buffer);
kono
parents:
diff changeset
1770 if (res_len > BUF_STACK_SZ)
kono
parents:
diff changeset
1771 free (result);
kono
parents:
diff changeset
1772 }
kono
parents:
diff changeset
1773
kono
parents:
diff changeset
1774
kono
parents:
diff changeset
1775 static void
kono
parents:
diff changeset
1776 write_complex (st_parameter_dt *dtp, const char *source, int kind, size_t size)
kono
parents:
diff changeset
1777 {
kono
parents:
diff changeset
1778 char semi_comma =
kono
parents:
diff changeset
1779 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
kono
parents:
diff changeset
1780
kono
parents:
diff changeset
1781 /* Set for no blanks so we get a string result with no leading
kono
parents:
diff changeset
1782 blanks. We will pad left later. */
kono
parents:
diff changeset
1783 dtp->u.p.g0_no_blanks = 1;
kono
parents:
diff changeset
1784
kono
parents:
diff changeset
1785 fnode f ;
kono
parents:
diff changeset
1786 char buf_stack[BUF_STACK_SZ];
kono
parents:
diff changeset
1787 char str1_buf[BUF_STACK_SZ];
kono
parents:
diff changeset
1788 char str2_buf[BUF_STACK_SZ];
kono
parents:
diff changeset
1789 char *buffer, *result1, *result2;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1790 size_t buf_size, res_len1, res_len2, flt_str_len1, flt_str_len2;
111
kono
parents:
diff changeset
1791 int width, lblanks, orig_scale = dtp->u.p.scale_factor;
kono
parents:
diff changeset
1792
kono
parents:
diff changeset
1793 dtp->u.p.scale_factor = 1;
kono
parents:
diff changeset
1794 set_fnode_default (dtp, &f, kind);
kono
parents:
diff changeset
1795
kono
parents:
diff changeset
1796 /* Set width for two values, parenthesis, and comma. */
kono
parents:
diff changeset
1797 width = 2 * f.u.real.w + 3;
kono
parents:
diff changeset
1798
kono
parents:
diff changeset
1799 /* Set for no blanks so we get a string result with no leading
kono
parents:
diff changeset
1800 blanks. We will pad left later. */
kono
parents:
diff changeset
1801 dtp->u.p.g0_no_blanks = 1;
kono
parents:
diff changeset
1802
kono
parents:
diff changeset
1803 /* Precision for snprintf call. */
kono
parents:
diff changeset
1804 int precision = get_precision (dtp, &f, source, kind);
kono
parents:
diff changeset
1805
kono
parents:
diff changeset
1806 /* String buffers to hold final result. */
kono
parents:
diff changeset
1807 result1 = select_string (dtp, &f, str1_buf, &res_len1, kind);
kono
parents:
diff changeset
1808 result2 = select_string (dtp, &f, str2_buf, &res_len2, kind);
kono
parents:
diff changeset
1809
kono
parents:
diff changeset
1810 buffer = select_buffer (dtp, &f, precision, buf_stack, &buf_size, kind);
kono
parents:
diff changeset
1811
kono
parents:
diff changeset
1812 get_float_string (dtp, &f, source , kind, 0, buffer,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1813 precision, buf_size, result1, &flt_str_len1);
111
kono
parents:
diff changeset
1814 get_float_string (dtp, &f, source + size / 2 , kind, 0, buffer,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1815 precision, buf_size, result2, &flt_str_len2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1816 if (!dtp->u.p.namelist_mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1817 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1818 lblanks = width - flt_str_len1 - flt_str_len2 - 3;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1819 write_x (dtp, lblanks, lblanks);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1820 }
111
kono
parents:
diff changeset
1821 write_char (dtp, '(');
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1822 write_float_string (dtp, result1, flt_str_len1);
111
kono
parents:
diff changeset
1823 write_char (dtp, semi_comma);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1824 write_float_string (dtp, result2, flt_str_len2);
111
kono
parents:
diff changeset
1825 write_char (dtp, ')');
kono
parents:
diff changeset
1826
kono
parents:
diff changeset
1827 dtp->u.p.scale_factor = orig_scale;
kono
parents:
diff changeset
1828 dtp->u.p.g0_no_blanks = 0;
kono
parents:
diff changeset
1829 if (buf_size > BUF_STACK_SZ)
kono
parents:
diff changeset
1830 free (buffer);
kono
parents:
diff changeset
1831 if (res_len1 > BUF_STACK_SZ)
kono
parents:
diff changeset
1832 free (result1);
kono
parents:
diff changeset
1833 if (res_len2 > BUF_STACK_SZ)
kono
parents:
diff changeset
1834 free (result2);
kono
parents:
diff changeset
1835 }
kono
parents:
diff changeset
1836
kono
parents:
diff changeset
1837
kono
parents:
diff changeset
1838 /* Write the separator between items. */
kono
parents:
diff changeset
1839
kono
parents:
diff changeset
1840 static void
kono
parents:
diff changeset
1841 write_separator (st_parameter_dt *dtp)
kono
parents:
diff changeset
1842 {
kono
parents:
diff changeset
1843 char *p;
kono
parents:
diff changeset
1844
kono
parents:
diff changeset
1845 p = write_block (dtp, options.separator_len);
kono
parents:
diff changeset
1846 if (p == NULL)
kono
parents:
diff changeset
1847 return;
kono
parents:
diff changeset
1848 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
1849 {
kono
parents:
diff changeset
1850 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
1851 memcpy4 (p4, options.separator, options.separator_len);
kono
parents:
diff changeset
1852 }
kono
parents:
diff changeset
1853 else
kono
parents:
diff changeset
1854 memcpy (p, options.separator, options.separator_len);
kono
parents:
diff changeset
1855 }
kono
parents:
diff changeset
1856
kono
parents:
diff changeset
1857
kono
parents:
diff changeset
1858 /* Write an item with list formatting.
kono
parents:
diff changeset
1859 TODO: handle skipping to the next record correctly, particularly
kono
parents:
diff changeset
1860 with strings. */
kono
parents:
diff changeset
1861
kono
parents:
diff changeset
1862 static void
kono
parents:
diff changeset
1863 list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
kono
parents:
diff changeset
1864 size_t size)
kono
parents:
diff changeset
1865 {
kono
parents:
diff changeset
1866 if (dtp->u.p.current_unit == NULL)
kono
parents:
diff changeset
1867 return;
kono
parents:
diff changeset
1868
kono
parents:
diff changeset
1869 if (dtp->u.p.first_item)
kono
parents:
diff changeset
1870 {
kono
parents:
diff changeset
1871 dtp->u.p.first_item = 0;
kono
parents:
diff changeset
1872 if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
kono
parents:
diff changeset
1873 write_char (dtp, ' ');
kono
parents:
diff changeset
1874 }
kono
parents:
diff changeset
1875 else
kono
parents:
diff changeset
1876 {
kono
parents:
diff changeset
1877 if (type != BT_CHARACTER || !dtp->u.p.char_flag ||
kono
parents:
diff changeset
1878 (dtp->u.p.current_unit->delim_status != DELIM_NONE
kono
parents:
diff changeset
1879 && dtp->u.p.current_unit->delim_status != DELIM_UNSPECIFIED))
kono
parents:
diff changeset
1880 write_separator (dtp);
kono
parents:
diff changeset
1881 }
kono
parents:
diff changeset
1882
kono
parents:
diff changeset
1883 switch (type)
kono
parents:
diff changeset
1884 {
kono
parents:
diff changeset
1885 case BT_INTEGER:
kono
parents:
diff changeset
1886 write_integer (dtp, p, kind);
kono
parents:
diff changeset
1887 break;
kono
parents:
diff changeset
1888 case BT_LOGICAL:
kono
parents:
diff changeset
1889 write_logical (dtp, p, kind);
kono
parents:
diff changeset
1890 break;
kono
parents:
diff changeset
1891 case BT_CHARACTER:
kono
parents:
diff changeset
1892 write_character (dtp, p, kind, size, DELIM);
kono
parents:
diff changeset
1893 break;
kono
parents:
diff changeset
1894 case BT_REAL:
kono
parents:
diff changeset
1895 write_real (dtp, p, kind);
kono
parents:
diff changeset
1896 break;
kono
parents:
diff changeset
1897 case BT_COMPLEX:
kono
parents:
diff changeset
1898 write_complex (dtp, p, kind, size);
kono
parents:
diff changeset
1899 break;
kono
parents:
diff changeset
1900 case BT_CLASS:
kono
parents:
diff changeset
1901 {
kono
parents:
diff changeset
1902 int unit = dtp->u.p.current_unit->unit_number;
kono
parents:
diff changeset
1903 char iotype[] = "LISTDIRECTED";
kono
parents:
diff changeset
1904 gfc_charlen_type iotype_len = 12;
kono
parents:
diff changeset
1905 char tmp_iomsg[IOMSG_LEN] = "";
kono
parents:
diff changeset
1906 char *child_iomsg;
kono
parents:
diff changeset
1907 gfc_charlen_type child_iomsg_len;
kono
parents:
diff changeset
1908 int noiostat;
kono
parents:
diff changeset
1909 int *child_iostat = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1910 gfc_full_array_i4 vlist;
111
kono
parents:
diff changeset
1911
kono
parents:
diff changeset
1912 GFC_DESCRIPTOR_DATA(&vlist) = NULL;
kono
parents:
diff changeset
1913 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
kono
parents:
diff changeset
1914
kono
parents:
diff changeset
1915 /* Set iostat, intent(out). */
kono
parents:
diff changeset
1916 noiostat = 0;
kono
parents:
diff changeset
1917 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
kono
parents:
diff changeset
1918 dtp->common.iostat : &noiostat;
kono
parents:
diff changeset
1919
kono
parents:
diff changeset
1920 /* Set iomsge, intent(inout). */
kono
parents:
diff changeset
1921 if (dtp->common.flags & IOPARM_HAS_IOMSG)
kono
parents:
diff changeset
1922 {
kono
parents:
diff changeset
1923 child_iomsg = dtp->common.iomsg;
kono
parents:
diff changeset
1924 child_iomsg_len = dtp->common.iomsg_len;
kono
parents:
diff changeset
1925 }
kono
parents:
diff changeset
1926 else
kono
parents:
diff changeset
1927 {
kono
parents:
diff changeset
1928 child_iomsg = tmp_iomsg;
kono
parents:
diff changeset
1929 child_iomsg_len = IOMSG_LEN;
kono
parents:
diff changeset
1930 }
kono
parents:
diff changeset
1931
kono
parents:
diff changeset
1932 /* Call the user defined formatted WRITE procedure. */
kono
parents:
diff changeset
1933 dtp->u.p.current_unit->child_dtio++;
kono
parents:
diff changeset
1934 dtp->u.p.fdtio_ptr (p, &unit, iotype, &vlist,
kono
parents:
diff changeset
1935 child_iostat, child_iomsg,
kono
parents:
diff changeset
1936 iotype_len, child_iomsg_len);
kono
parents:
diff changeset
1937 dtp->u.p.current_unit->child_dtio--;
kono
parents:
diff changeset
1938 }
kono
parents:
diff changeset
1939 break;
kono
parents:
diff changeset
1940 default:
kono
parents:
diff changeset
1941 internal_error (&dtp->common, "list_formatted_write(): Bad type");
kono
parents:
diff changeset
1942 }
kono
parents:
diff changeset
1943
kono
parents:
diff changeset
1944 fbuf_flush_list (dtp->u.p.current_unit, LIST_WRITING);
kono
parents:
diff changeset
1945 dtp->u.p.char_flag = (type == BT_CHARACTER);
kono
parents:
diff changeset
1946 }
kono
parents:
diff changeset
1947
kono
parents:
diff changeset
1948
kono
parents:
diff changeset
1949 void
kono
parents:
diff changeset
1950 list_formatted_write (st_parameter_dt *dtp, bt type, void *p, int kind,
kono
parents:
diff changeset
1951 size_t size, size_t nelems)
kono
parents:
diff changeset
1952 {
kono
parents:
diff changeset
1953 size_t elem;
kono
parents:
diff changeset
1954 char *tmp;
kono
parents:
diff changeset
1955 size_t stride = type == BT_CHARACTER ?
kono
parents:
diff changeset
1956 size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
kono
parents:
diff changeset
1957
kono
parents:
diff changeset
1958 tmp = (char *) p;
kono
parents:
diff changeset
1959
kono
parents:
diff changeset
1960 /* Big loop over all the elements. */
kono
parents:
diff changeset
1961 for (elem = 0; elem < nelems; elem++)
kono
parents:
diff changeset
1962 {
kono
parents:
diff changeset
1963 dtp->u.p.item_count++;
kono
parents:
diff changeset
1964 list_formatted_write_scalar (dtp, type, tmp + elem * stride, kind, size);
kono
parents:
diff changeset
1965 }
kono
parents:
diff changeset
1966 }
kono
parents:
diff changeset
1967
kono
parents:
diff changeset
1968 /* NAMELIST OUTPUT
kono
parents:
diff changeset
1969
kono
parents:
diff changeset
1970 nml_write_obj writes a namelist object to the output stream. It is called
kono
parents:
diff changeset
1971 recursively for derived type components:
kono
parents:
diff changeset
1972 obj = is the namelist_info for the current object.
kono
parents:
diff changeset
1973 offset = the offset relative to the address held by the object for
kono
parents:
diff changeset
1974 derived type arrays.
kono
parents:
diff changeset
1975 base = is the namelist_info of the derived type, when obj is a
kono
parents:
diff changeset
1976 component.
kono
parents:
diff changeset
1977 base_name = the full name for a derived type, including qualifiers
kono
parents:
diff changeset
1978 if any.
kono
parents:
diff changeset
1979 The returned value is a pointer to the object beyond the last one
kono
parents:
diff changeset
1980 accessed, including nested derived types. Notice that the namelist is
kono
parents:
diff changeset
1981 a linear linked list of objects, including derived types and their
kono
parents:
diff changeset
1982 components. A tree, of sorts, is implied by the compound names of
kono
parents:
diff changeset
1983 the derived type components and this is how this function recurses through
kono
parents:
diff changeset
1984 the list. */
kono
parents:
diff changeset
1985
kono
parents:
diff changeset
1986 /* A generous estimate of the number of characters needed to print
kono
parents:
diff changeset
1987 repeat counts and indices, including commas, asterices and brackets. */
kono
parents:
diff changeset
1988
kono
parents:
diff changeset
1989 #define NML_DIGITS 20
kono
parents:
diff changeset
1990
kono
parents:
diff changeset
1991 static void
kono
parents:
diff changeset
1992 namelist_write_newline (st_parameter_dt *dtp)
kono
parents:
diff changeset
1993 {
kono
parents:
diff changeset
1994 if (!is_internal_unit (dtp))
kono
parents:
diff changeset
1995 {
kono
parents:
diff changeset
1996 #ifdef HAVE_CRLF
kono
parents:
diff changeset
1997 write_character (dtp, "\r\n", 1, 2, NODELIM);
kono
parents:
diff changeset
1998 #else
kono
parents:
diff changeset
1999 write_character (dtp, "\n", 1, 1, NODELIM);
kono
parents:
diff changeset
2000 #endif
kono
parents:
diff changeset
2001 return;
kono
parents:
diff changeset
2002 }
kono
parents:
diff changeset
2003
kono
parents:
diff changeset
2004 if (is_array_io (dtp))
kono
parents:
diff changeset
2005 {
kono
parents:
diff changeset
2006 gfc_offset record;
kono
parents:
diff changeset
2007 int finished;
kono
parents:
diff changeset
2008 char *p;
kono
parents:
diff changeset
2009 int length = dtp->u.p.current_unit->bytes_left;
kono
parents:
diff changeset
2010
kono
parents:
diff changeset
2011 p = write_block (dtp, length);
kono
parents:
diff changeset
2012 if (p == NULL)
kono
parents:
diff changeset
2013 return;
kono
parents:
diff changeset
2014
kono
parents:
diff changeset
2015 if (unlikely (is_char4_unit (dtp)))
kono
parents:
diff changeset
2016 {
kono
parents:
diff changeset
2017 gfc_char4_t *p4 = (gfc_char4_t *) p;
kono
parents:
diff changeset
2018 memset4 (p4, ' ', length);
kono
parents:
diff changeset
2019 }
kono
parents:
diff changeset
2020 else
kono
parents:
diff changeset
2021 memset (p, ' ', length);
kono
parents:
diff changeset
2022
kono
parents:
diff changeset
2023 /* Now that the current record has been padded out,
kono
parents:
diff changeset
2024 determine where the next record in the array is. */
kono
parents:
diff changeset
2025 record = next_array_record (dtp, dtp->u.p.current_unit->ls,
kono
parents:
diff changeset
2026 &finished);
kono
parents:
diff changeset
2027 if (finished)
kono
parents:
diff changeset
2028 dtp->u.p.current_unit->endfile = AT_ENDFILE;
kono
parents:
diff changeset
2029 else
kono
parents:
diff changeset
2030 {
kono
parents:
diff changeset
2031 /* Now seek to this record */
kono
parents:
diff changeset
2032 record = record * dtp->u.p.current_unit->recl;
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
kono
parents:
diff changeset
2035 {
kono
parents:
diff changeset
2036 generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
kono
parents:
diff changeset
2037 return;
kono
parents:
diff changeset
2038 }
kono
parents:
diff changeset
2039
kono
parents:
diff changeset
2040 dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
kono
parents:
diff changeset
2041 }
kono
parents:
diff changeset
2042 }
kono
parents:
diff changeset
2043 else
kono
parents:
diff changeset
2044 write_character (dtp, " ", 1, 1, NODELIM);
kono
parents:
diff changeset
2045 }
kono
parents:
diff changeset
2046
kono
parents:
diff changeset
2047
kono
parents:
diff changeset
2048 static namelist_info *
kono
parents:
diff changeset
2049 nml_write_obj (st_parameter_dt *dtp, namelist_info *obj, index_type offset,
kono
parents:
diff changeset
2050 namelist_info *base, char *base_name)
kono
parents:
diff changeset
2051 {
kono
parents:
diff changeset
2052 int rep_ctr;
kono
parents:
diff changeset
2053 int num;
kono
parents:
diff changeset
2054 int nml_carry;
kono
parents:
diff changeset
2055 int len;
kono
parents:
diff changeset
2056 index_type obj_size;
kono
parents:
diff changeset
2057 index_type nelem;
kono
parents:
diff changeset
2058 size_t dim_i;
kono
parents:
diff changeset
2059 size_t clen;
kono
parents:
diff changeset
2060 index_type elem_ctr;
kono
parents:
diff changeset
2061 size_t obj_name_len;
kono
parents:
diff changeset
2062 void *p;
kono
parents:
diff changeset
2063 char cup;
kono
parents:
diff changeset
2064 char *obj_name;
kono
parents:
diff changeset
2065 char *ext_name;
kono
parents:
diff changeset
2066 char *q;
kono
parents:
diff changeset
2067 size_t ext_name_len;
kono
parents:
diff changeset
2068 char rep_buff[NML_DIGITS];
kono
parents:
diff changeset
2069 namelist_info *cmp;
kono
parents:
diff changeset
2070 namelist_info *retval = obj->next;
kono
parents:
diff changeset
2071 size_t base_name_len;
kono
parents:
diff changeset
2072 size_t base_var_name_len;
kono
parents:
diff changeset
2073 size_t tot_len;
kono
parents:
diff changeset
2074
kono
parents:
diff changeset
2075 /* Set the character to be used to separate values
kono
parents:
diff changeset
2076 to a comma or semi-colon. */
kono
parents:
diff changeset
2077
kono
parents:
diff changeset
2078 char semi_comma =
kono
parents:
diff changeset
2079 dtp->u.p.current_unit->decimal_status == DECIMAL_POINT ? ',' : ';';
kono
parents:
diff changeset
2080
kono
parents:
diff changeset
2081 /* Write namelist variable names in upper case. If a derived type,
kono
parents:
diff changeset
2082 nothing is output. If a component, base and base_name are set. */
kono
parents:
diff changeset
2083
kono
parents:
diff changeset
2084 if (obj->type != BT_DERIVED || obj->dtio_sub != NULL)
kono
parents:
diff changeset
2085 {
kono
parents:
diff changeset
2086 namelist_write_newline (dtp);
kono
parents:
diff changeset
2087 write_character (dtp, " ", 1, 1, NODELIM);
kono
parents:
diff changeset
2088
kono
parents:
diff changeset
2089 len = 0;
kono
parents:
diff changeset
2090 if (base)
kono
parents:
diff changeset
2091 {
kono
parents:
diff changeset
2092 len = strlen (base->var_name);
kono
parents:
diff changeset
2093 base_name_len = strlen (base_name);
kono
parents:
diff changeset
2094 for (dim_i = 0; dim_i < base_name_len; dim_i++)
kono
parents:
diff changeset
2095 {
kono
parents:
diff changeset
2096 cup = toupper ((int) base_name[dim_i]);
kono
parents:
diff changeset
2097 write_character (dtp, &cup, 1, 1, NODELIM);
kono
parents:
diff changeset
2098 }
kono
parents:
diff changeset
2099 }
kono
parents:
diff changeset
2100 clen = strlen (obj->var_name);
kono
parents:
diff changeset
2101 for (dim_i = len; dim_i < clen; dim_i++)
kono
parents:
diff changeset
2102 {
kono
parents:
diff changeset
2103 cup = toupper ((int) obj->var_name[dim_i]);
kono
parents:
diff changeset
2104 if (cup == '+')
kono
parents:
diff changeset
2105 cup = '%';
kono
parents:
diff changeset
2106 write_character (dtp, &cup, 1, 1, NODELIM);
kono
parents:
diff changeset
2107 }
kono
parents:
diff changeset
2108 write_character (dtp, "=", 1, 1, NODELIM);
kono
parents:
diff changeset
2109 }
kono
parents:
diff changeset
2110
kono
parents:
diff changeset
2111 /* Counts the number of data output on a line, including names. */
kono
parents:
diff changeset
2112
kono
parents:
diff changeset
2113 num = 1;
kono
parents:
diff changeset
2114
kono
parents:
diff changeset
2115 len = obj->len;
kono
parents:
diff changeset
2116
kono
parents:
diff changeset
2117 switch (obj->type)
kono
parents:
diff changeset
2118 {
kono
parents:
diff changeset
2119
kono
parents:
diff changeset
2120 case BT_REAL:
kono
parents:
diff changeset
2121 obj_size = size_from_real_kind (len);
kono
parents:
diff changeset
2122 break;
kono
parents:
diff changeset
2123
kono
parents:
diff changeset
2124 case BT_COMPLEX:
kono
parents:
diff changeset
2125 obj_size = size_from_complex_kind (len);
kono
parents:
diff changeset
2126 break;
kono
parents:
diff changeset
2127
kono
parents:
diff changeset
2128 case BT_CHARACTER:
kono
parents:
diff changeset
2129 obj_size = obj->string_length;
kono
parents:
diff changeset
2130 break;
kono
parents:
diff changeset
2131
kono
parents:
diff changeset
2132 default:
kono
parents:
diff changeset
2133 obj_size = len;
kono
parents:
diff changeset
2134 }
kono
parents:
diff changeset
2135
kono
parents:
diff changeset
2136 if (obj->var_rank)
kono
parents:
diff changeset
2137 obj_size = obj->size;
kono
parents:
diff changeset
2138
kono
parents:
diff changeset
2139 /* Set the index vector and count the number of elements. */
kono
parents:
diff changeset
2140
kono
parents:
diff changeset
2141 nelem = 1;
kono
parents:
diff changeset
2142 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
kono
parents:
diff changeset
2143 {
kono
parents:
diff changeset
2144 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj, dim_i);
kono
parents:
diff changeset
2145 nelem = nelem * GFC_DESCRIPTOR_EXTENT (obj, dim_i);
kono
parents:
diff changeset
2146 }
kono
parents:
diff changeset
2147
kono
parents:
diff changeset
2148 /* Main loop to output the data held in the object. */
kono
parents:
diff changeset
2149
kono
parents:
diff changeset
2150 rep_ctr = 1;
kono
parents:
diff changeset
2151 for (elem_ctr = 0; elem_ctr < nelem; elem_ctr++)
kono
parents:
diff changeset
2152 {
kono
parents:
diff changeset
2153
kono
parents:
diff changeset
2154 /* Build the pointer to the data value. The offset is passed by
kono
parents:
diff changeset
2155 recursive calls to this function for arrays of derived types.
kono
parents:
diff changeset
2156 Is NULL otherwise. */
kono
parents:
diff changeset
2157
kono
parents:
diff changeset
2158 p = (void *)(obj->mem_pos + elem_ctr * obj_size);
kono
parents:
diff changeset
2159 p += offset;
kono
parents:
diff changeset
2160
kono
parents:
diff changeset
2161 /* Check for repeat counts of intrinsic types. */
kono
parents:
diff changeset
2162
kono
parents:
diff changeset
2163 if ((elem_ctr < (nelem - 1)) &&
kono
parents:
diff changeset
2164 (obj->type != BT_DERIVED) &&
kono
parents:
diff changeset
2165 !memcmp (p, (void *)(p + obj_size ), obj_size ))
kono
parents:
diff changeset
2166 {
kono
parents:
diff changeset
2167 rep_ctr++;
kono
parents:
diff changeset
2168 }
kono
parents:
diff changeset
2169
kono
parents:
diff changeset
2170 /* Execute a repeated output. Note the flag no_leading_blank that
kono
parents:
diff changeset
2171 is used in the functions used to output the intrinsic types. */
kono
parents:
diff changeset
2172
kono
parents:
diff changeset
2173 else
kono
parents:
diff changeset
2174 {
kono
parents:
diff changeset
2175 if (rep_ctr > 1)
kono
parents:
diff changeset
2176 {
kono
parents:
diff changeset
2177 snprintf(rep_buff, NML_DIGITS, " %d*", rep_ctr);
kono
parents:
diff changeset
2178 write_character (dtp, rep_buff, 1, strlen (rep_buff), NODELIM);
kono
parents:
diff changeset
2179 dtp->u.p.no_leading_blank = 1;
kono
parents:
diff changeset
2180 }
kono
parents:
diff changeset
2181 num++;
kono
parents:
diff changeset
2182
kono
parents:
diff changeset
2183 /* Output the data, if an intrinsic type, or recurse into this
kono
parents:
diff changeset
2184 routine to treat derived types. */
kono
parents:
diff changeset
2185
kono
parents:
diff changeset
2186 switch (obj->type)
kono
parents:
diff changeset
2187 {
kono
parents:
diff changeset
2188
kono
parents:
diff changeset
2189 case BT_INTEGER:
kono
parents:
diff changeset
2190 write_integer (dtp, p, len);
kono
parents:
diff changeset
2191 break;
kono
parents:
diff changeset
2192
kono
parents:
diff changeset
2193 case BT_LOGICAL:
kono
parents:
diff changeset
2194 write_logical (dtp, p, len);
kono
parents:
diff changeset
2195 break;
kono
parents:
diff changeset
2196
kono
parents:
diff changeset
2197 case BT_CHARACTER:
kono
parents:
diff changeset
2198 if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
kono
parents:
diff changeset
2199 write_character (dtp, p, 4, obj->string_length, DELIM);
kono
parents:
diff changeset
2200 else
kono
parents:
diff changeset
2201 write_character (dtp, p, 1, obj->string_length, DELIM);
kono
parents:
diff changeset
2202 break;
kono
parents:
diff changeset
2203
kono
parents:
diff changeset
2204 case BT_REAL:
kono
parents:
diff changeset
2205 write_real (dtp, p, len);
kono
parents:
diff changeset
2206 break;
kono
parents:
diff changeset
2207
kono
parents:
diff changeset
2208 case BT_COMPLEX:
kono
parents:
diff changeset
2209 dtp->u.p.no_leading_blank = 0;
kono
parents:
diff changeset
2210 num++;
kono
parents:
diff changeset
2211 write_complex (dtp, p, len, obj_size);
kono
parents:
diff changeset
2212 break;
kono
parents:
diff changeset
2213
kono
parents:
diff changeset
2214 case BT_DERIVED:
kono
parents:
diff changeset
2215 case BT_CLASS:
kono
parents:
diff changeset
2216 /* To treat a derived type, we need to build two strings:
kono
parents:
diff changeset
2217 ext_name = the name, including qualifiers that prepends
kono
parents:
diff changeset
2218 component names in the output - passed to
kono
parents:
diff changeset
2219 nml_write_obj.
kono
parents:
diff changeset
2220 obj_name = the derived type name with no qualifiers but %
kono
parents:
diff changeset
2221 appended. This is used to identify the
kono
parents:
diff changeset
2222 components. */
kono
parents:
diff changeset
2223
kono
parents:
diff changeset
2224 /* First ext_name => get length of all possible components */
kono
parents:
diff changeset
2225 if (obj->dtio_sub != NULL)
kono
parents:
diff changeset
2226 {
kono
parents:
diff changeset
2227 int unit = dtp->u.p.current_unit->unit_number;
kono
parents:
diff changeset
2228 char iotype[] = "NAMELIST";
kono
parents:
diff changeset
2229 gfc_charlen_type iotype_len = 8;
kono
parents:
diff changeset
2230 char tmp_iomsg[IOMSG_LEN] = "";
kono
parents:
diff changeset
2231 char *child_iomsg;
kono
parents:
diff changeset
2232 gfc_charlen_type child_iomsg_len;
kono
parents:
diff changeset
2233 int noiostat;
kono
parents:
diff changeset
2234 int *child_iostat = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2235 gfc_full_array_i4 vlist;
111
kono
parents:
diff changeset
2236 formatted_dtio dtio_ptr = (formatted_dtio)obj->dtio_sub;
kono
parents:
diff changeset
2237
kono
parents:
diff changeset
2238 GFC_DIMENSION_SET(vlist.dim[0],1, 0, 0);
kono
parents:
diff changeset
2239
kono
parents:
diff changeset
2240 /* Set iostat, intent(out). */
kono
parents:
diff changeset
2241 noiostat = 0;
kono
parents:
diff changeset
2242 child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
kono
parents:
diff changeset
2243 dtp->common.iostat : &noiostat;
kono
parents:
diff changeset
2244
kono
parents:
diff changeset
2245 /* Set iomsg, intent(inout). */
kono
parents:
diff changeset
2246 if (dtp->common.flags & IOPARM_HAS_IOMSG)
kono
parents:
diff changeset
2247 {
kono
parents:
diff changeset
2248 child_iomsg = dtp->common.iomsg;
kono
parents:
diff changeset
2249 child_iomsg_len = dtp->common.iomsg_len;
kono
parents:
diff changeset
2250 }
kono
parents:
diff changeset
2251 else
kono
parents:
diff changeset
2252 {
kono
parents:
diff changeset
2253 child_iomsg = tmp_iomsg;
kono
parents:
diff changeset
2254 child_iomsg_len = IOMSG_LEN;
kono
parents:
diff changeset
2255 }
kono
parents:
diff changeset
2256
kono
parents:
diff changeset
2257 /* Call the user defined formatted WRITE procedure. */
kono
parents:
diff changeset
2258 dtp->u.p.current_unit->child_dtio++;
kono
parents:
diff changeset
2259 if (obj->type == BT_DERIVED)
kono
parents:
diff changeset
2260 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2261 /* Build a class container. */
111
kono
parents:
diff changeset
2262 gfc_class list_obj;
kono
parents:
diff changeset
2263 list_obj.data = p;
kono
parents:
diff changeset
2264 list_obj.vptr = obj->vtable;
kono
parents:
diff changeset
2265 list_obj.len = 0;
kono
parents:
diff changeset
2266 dtio_ptr ((void *)&list_obj, &unit, iotype, &vlist,
kono
parents:
diff changeset
2267 child_iostat, child_iomsg,
kono
parents:
diff changeset
2268 iotype_len, child_iomsg_len);
kono
parents:
diff changeset
2269 }
kono
parents:
diff changeset
2270 else
kono
parents:
diff changeset
2271 {
kono
parents:
diff changeset
2272 dtio_ptr (p, &unit, iotype, &vlist,
kono
parents:
diff changeset
2273 child_iostat, child_iomsg,
kono
parents:
diff changeset
2274 iotype_len, child_iomsg_len);
kono
parents:
diff changeset
2275 }
kono
parents:
diff changeset
2276 dtp->u.p.current_unit->child_dtio--;
kono
parents:
diff changeset
2277
kono
parents:
diff changeset
2278 goto obj_loop;
kono
parents:
diff changeset
2279 }
kono
parents:
diff changeset
2280
kono
parents:
diff changeset
2281 base_name_len = base_name ? strlen (base_name) : 0;
kono
parents:
diff changeset
2282 base_var_name_len = base ? strlen (base->var_name) : 0;
kono
parents:
diff changeset
2283 ext_name_len = base_name_len + base_var_name_len
kono
parents:
diff changeset
2284 + strlen (obj->var_name) + obj->var_rank * NML_DIGITS + 1;
kono
parents:
diff changeset
2285 ext_name = xmalloc (ext_name_len);
kono
parents:
diff changeset
2286
kono
parents:
diff changeset
2287 if (base_name)
kono
parents:
diff changeset
2288 memcpy (ext_name, base_name, base_name_len);
kono
parents:
diff changeset
2289 clen = strlen (obj->var_name + base_var_name_len);
kono
parents:
diff changeset
2290 memcpy (ext_name + base_name_len,
kono
parents:
diff changeset
2291 obj->var_name + base_var_name_len, clen);
kono
parents:
diff changeset
2292
kono
parents:
diff changeset
2293 /* Append the qualifier. */
kono
parents:
diff changeset
2294
kono
parents:
diff changeset
2295 tot_len = base_name_len + clen;
kono
parents:
diff changeset
2296 for (dim_i = 0; dim_i < (size_t) obj->var_rank; dim_i++)
kono
parents:
diff changeset
2297 {
kono
parents:
diff changeset
2298 if (!dim_i)
kono
parents:
diff changeset
2299 {
kono
parents:
diff changeset
2300 ext_name[tot_len] = '(';
kono
parents:
diff changeset
2301 tot_len++;
kono
parents:
diff changeset
2302 }
kono
parents:
diff changeset
2303 snprintf (ext_name + tot_len, ext_name_len - tot_len, "%d",
kono
parents:
diff changeset
2304 (int) obj->ls[dim_i].idx);
kono
parents:
diff changeset
2305 tot_len += strlen (ext_name + tot_len);
kono
parents:
diff changeset
2306 ext_name[tot_len] = ((int) dim_i == obj->var_rank - 1) ? ')' : ',';
kono
parents:
diff changeset
2307 tot_len++;
kono
parents:
diff changeset
2308 }
kono
parents:
diff changeset
2309
kono
parents:
diff changeset
2310 ext_name[tot_len] = '\0';
kono
parents:
diff changeset
2311 for (q = ext_name; *q; q++)
kono
parents:
diff changeset
2312 if (*q == '+')
kono
parents:
diff changeset
2313 *q = '%';
kono
parents:
diff changeset
2314
kono
parents:
diff changeset
2315 /* Now obj_name. */
kono
parents:
diff changeset
2316
kono
parents:
diff changeset
2317 obj_name_len = strlen (obj->var_name) + 1;
kono
parents:
diff changeset
2318 obj_name = xmalloc (obj_name_len + 1);
kono
parents:
diff changeset
2319 memcpy (obj_name, obj->var_name, obj_name_len-1);
kono
parents:
diff changeset
2320 memcpy (obj_name + obj_name_len-1, "%", 2);
kono
parents:
diff changeset
2321
kono
parents:
diff changeset
2322 /* Now loop over the components. Update the component pointer
kono
parents:
diff changeset
2323 with the return value from nml_write_obj => this loop jumps
kono
parents:
diff changeset
2324 past nested derived types. */
kono
parents:
diff changeset
2325
kono
parents:
diff changeset
2326 for (cmp = obj->next;
kono
parents:
diff changeset
2327 cmp && !strncmp (cmp->var_name, obj_name, obj_name_len);
kono
parents:
diff changeset
2328 cmp = retval)
kono
parents:
diff changeset
2329 {
kono
parents:
diff changeset
2330 retval = nml_write_obj (dtp, cmp,
kono
parents:
diff changeset
2331 (index_type)(p - obj->mem_pos),
kono
parents:
diff changeset
2332 obj, ext_name);
kono
parents:
diff changeset
2333 }
kono
parents:
diff changeset
2334
kono
parents:
diff changeset
2335 free (obj_name);
kono
parents:
diff changeset
2336 free (ext_name);
kono
parents:
diff changeset
2337 goto obj_loop;
kono
parents:
diff changeset
2338
kono
parents:
diff changeset
2339 default:
kono
parents:
diff changeset
2340 internal_error (&dtp->common, "Bad type for namelist write");
kono
parents:
diff changeset
2341 }
kono
parents:
diff changeset
2342
kono
parents:
diff changeset
2343 /* Reset the leading blank suppression, write a comma (or semi-colon)
kono
parents:
diff changeset
2344 and, if 5 values have been output, write a newline and advance
kono
parents:
diff changeset
2345 to column 2. Reset the repeat counter. */
kono
parents:
diff changeset
2346
kono
parents:
diff changeset
2347 dtp->u.p.no_leading_blank = 0;
kono
parents:
diff changeset
2348 if (obj->type == BT_CHARACTER)
kono
parents:
diff changeset
2349 {
kono
parents:
diff changeset
2350 if (dtp->u.p.nml_delim != '\0')
kono
parents:
diff changeset
2351 write_character (dtp, &semi_comma, 1, 1, NODELIM);
kono
parents:
diff changeset
2352 }
kono
parents:
diff changeset
2353 else
kono
parents:
diff changeset
2354 write_character (dtp, &semi_comma, 1, 1, NODELIM);
kono
parents:
diff changeset
2355 if (num > 5)
kono
parents:
diff changeset
2356 {
kono
parents:
diff changeset
2357 num = 0;
kono
parents:
diff changeset
2358 if (dtp->u.p.nml_delim == '\0')
kono
parents:
diff changeset
2359 write_character (dtp, &semi_comma, 1, 1, NODELIM);
kono
parents:
diff changeset
2360 namelist_write_newline (dtp);
kono
parents:
diff changeset
2361 write_character (dtp, " ", 1, 1, NODELIM);
kono
parents:
diff changeset
2362 }
kono
parents:
diff changeset
2363 rep_ctr = 1;
kono
parents:
diff changeset
2364 }
kono
parents:
diff changeset
2365
kono
parents:
diff changeset
2366 /* Cycle through and increment the index vector. */
kono
parents:
diff changeset
2367
kono
parents:
diff changeset
2368 obj_loop:
kono
parents:
diff changeset
2369
kono
parents:
diff changeset
2370 nml_carry = 1;
kono
parents:
diff changeset
2371 for (dim_i = 0; nml_carry && (dim_i < (size_t) obj->var_rank); dim_i++)
kono
parents:
diff changeset
2372 {
kono
parents:
diff changeset
2373 obj->ls[dim_i].idx += nml_carry ;
kono
parents:
diff changeset
2374 nml_carry = 0;
kono
parents:
diff changeset
2375 if (obj->ls[dim_i].idx > GFC_DESCRIPTOR_UBOUND(obj,dim_i))
kono
parents:
diff changeset
2376 {
kono
parents:
diff changeset
2377 obj->ls[dim_i].idx = GFC_DESCRIPTOR_LBOUND(obj,dim_i);
kono
parents:
diff changeset
2378 nml_carry = 1;
kono
parents:
diff changeset
2379 }
kono
parents:
diff changeset
2380 }
kono
parents:
diff changeset
2381 }
kono
parents:
diff changeset
2382
kono
parents:
diff changeset
2383 /* Return a pointer beyond the furthest object accessed. */
kono
parents:
diff changeset
2384
kono
parents:
diff changeset
2385 return retval;
kono
parents:
diff changeset
2386 }
kono
parents:
diff changeset
2387
kono
parents:
diff changeset
2388
kono
parents:
diff changeset
2389 /* This is the entry function for namelist writes. It outputs the name
kono
parents:
diff changeset
2390 of the namelist and iterates through the namelist by calls to
kono
parents:
diff changeset
2391 nml_write_obj. The call below has dummys in the arguments used in
kono
parents:
diff changeset
2392 the treatment of derived types. */
kono
parents:
diff changeset
2393
kono
parents:
diff changeset
2394 void
kono
parents:
diff changeset
2395 namelist_write (st_parameter_dt *dtp)
kono
parents:
diff changeset
2396 {
kono
parents:
diff changeset
2397 namelist_info *t1, *t2, *dummy = NULL;
kono
parents:
diff changeset
2398 index_type dummy_offset = 0;
kono
parents:
diff changeset
2399 char c;
kono
parents:
diff changeset
2400 char *dummy_name = NULL;
kono
parents:
diff changeset
2401
kono
parents:
diff changeset
2402 /* Set the delimiter for namelist output. */
kono
parents:
diff changeset
2403 switch (dtp->u.p.current_unit->delim_status)
kono
parents:
diff changeset
2404 {
kono
parents:
diff changeset
2405 case DELIM_APOSTROPHE:
kono
parents:
diff changeset
2406 dtp->u.p.nml_delim = '\'';
kono
parents:
diff changeset
2407 break;
kono
parents:
diff changeset
2408 case DELIM_QUOTE:
kono
parents:
diff changeset
2409 case DELIM_UNSPECIFIED:
kono
parents:
diff changeset
2410 dtp->u.p.nml_delim = '"';
kono
parents:
diff changeset
2411 break;
kono
parents:
diff changeset
2412 default:
kono
parents:
diff changeset
2413 dtp->u.p.nml_delim = '\0';
kono
parents:
diff changeset
2414 }
kono
parents:
diff changeset
2415
kono
parents:
diff changeset
2416 write_character (dtp, "&", 1, 1, NODELIM);
kono
parents:
diff changeset
2417
kono
parents:
diff changeset
2418 /* Write namelist name in upper case - f95 std. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2419 for (gfc_charlen_type i = 0; i < dtp->namelist_name_len; i++ )
111
kono
parents:
diff changeset
2420 {
kono
parents:
diff changeset
2421 c = toupper ((int) dtp->namelist_name[i]);
kono
parents:
diff changeset
2422 write_character (dtp, &c, 1 ,1, NODELIM);
kono
parents:
diff changeset
2423 }
kono
parents:
diff changeset
2424
kono
parents:
diff changeset
2425 if (dtp->u.p.ionml != NULL)
kono
parents:
diff changeset
2426 {
kono
parents:
diff changeset
2427 t1 = dtp->u.p.ionml;
kono
parents:
diff changeset
2428 while (t1 != NULL)
kono
parents:
diff changeset
2429 {
kono
parents:
diff changeset
2430 t2 = t1;
kono
parents:
diff changeset
2431 t1 = nml_write_obj (dtp, t2, dummy_offset, dummy, dummy_name);
kono
parents:
diff changeset
2432 }
kono
parents:
diff changeset
2433 }
kono
parents:
diff changeset
2434
kono
parents:
diff changeset
2435 namelist_write_newline (dtp);
kono
parents:
diff changeset
2436 write_character (dtp, " /", 1, 2, NODELIM);
kono
parents:
diff changeset
2437 }
kono
parents:
diff changeset
2438
kono
parents:
diff changeset
2439 #undef NML_DIGITS