transfer.c revision 1.1.1.3 1 1.1.1.3 mrg /* Copyright (C) 2002-2022 Free Software Foundation, Inc.
2 1.1 mrg Contributed by Andy Vaught
3 1.1 mrg Namelist transfer functions contributed by Paul Thomas
4 1.1 mrg F2003 I/O support contributed by Jerry DeLisle
5 1.1 mrg
6 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran).
7 1.1 mrg
8 1.1 mrg Libgfortran is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
11 1.1 mrg any later version.
12 1.1 mrg
13 1.1 mrg Libgfortran is distributed in the hope that it will be useful,
14 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 mrg GNU General Public License for more details.
17 1.1 mrg
18 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
19 1.1 mrg permissions described in the GCC Runtime Library Exception, version
20 1.1 mrg 3.1, as published by the Free Software Foundation.
21 1.1 mrg
22 1.1 mrg You should have received a copy of the GNU General Public License and
23 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
24 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 1.1 mrg <http://www.gnu.org/licenses/>. */
26 1.1 mrg
27 1.1 mrg
28 1.1 mrg /* transfer.c -- Top level handling of data transfer statements. */
29 1.1 mrg
30 1.1 mrg #include "io.h"
31 1.1 mrg #include "fbuf.h"
32 1.1 mrg #include "format.h"
33 1.1 mrg #include "unix.h"
34 1.1 mrg #include "async.h"
35 1.1 mrg #include <string.h>
36 1.1 mrg #include <errno.h>
37 1.1 mrg
38 1.1 mrg
39 1.1 mrg /* Calling conventions: Data transfer statements are unlike other
40 1.1 mrg library calls in that they extend over several calls.
41 1.1 mrg
42 1.1 mrg The first call is always a call to st_read() or st_write(). These
43 1.1 mrg subroutines return no status unless a namelist read or write is
44 1.1 mrg being done, in which case there is the usual status. No further
45 1.1 mrg calls are necessary in this case.
46 1.1 mrg
47 1.1 mrg For other sorts of data transfer, there are zero or more data
48 1.1 mrg transfer statement that depend on the format of the data transfer
49 1.1 mrg statement. For READ (and for backwards compatibily: for WRITE), one has
50 1.1 mrg
51 1.1 mrg transfer_integer
52 1.1 mrg transfer_logical
53 1.1 mrg transfer_character
54 1.1 mrg transfer_character_wide
55 1.1 mrg transfer_real
56 1.1 mrg transfer_complex
57 1.1 mrg transfer_real128
58 1.1 mrg transfer_complex128
59 1.1 mrg
60 1.1 mrg and for WRITE
61 1.1 mrg
62 1.1 mrg transfer_integer_write
63 1.1 mrg transfer_logical_write
64 1.1 mrg transfer_character_write
65 1.1 mrg transfer_character_wide_write
66 1.1 mrg transfer_real_write
67 1.1 mrg transfer_complex_write
68 1.1 mrg transfer_real128_write
69 1.1 mrg transfer_complex128_write
70 1.1 mrg
71 1.1 mrg These subroutines do not return status. The *128 functions
72 1.1 mrg are in the file transfer128.c.
73 1.1 mrg
74 1.1 mrg The last call is a call to st_[read|write]_done(). While
75 1.1 mrg something can easily go wrong with the initial st_read() or
76 1.1 mrg st_write(), an error inhibits any data from actually being
77 1.1 mrg transferred. */
78 1.1 mrg
79 1.1 mrg extern void transfer_integer (st_parameter_dt *, void *, int);
80 1.1 mrg export_proto(transfer_integer);
81 1.1 mrg
82 1.1 mrg extern void transfer_integer_write (st_parameter_dt *, void *, int);
83 1.1 mrg export_proto(transfer_integer_write);
84 1.1 mrg
85 1.1 mrg extern void transfer_real (st_parameter_dt *, void *, int);
86 1.1 mrg export_proto(transfer_real);
87 1.1 mrg
88 1.1 mrg extern void transfer_real_write (st_parameter_dt *, void *, int);
89 1.1 mrg export_proto(transfer_real_write);
90 1.1 mrg
91 1.1 mrg extern void transfer_logical (st_parameter_dt *, void *, int);
92 1.1 mrg export_proto(transfer_logical);
93 1.1 mrg
94 1.1 mrg extern void transfer_logical_write (st_parameter_dt *, void *, int);
95 1.1 mrg export_proto(transfer_logical_write);
96 1.1 mrg
97 1.1 mrg extern void transfer_character (st_parameter_dt *, void *, gfc_charlen_type);
98 1.1 mrg export_proto(transfer_character);
99 1.1 mrg
100 1.1 mrg extern void transfer_character_write (st_parameter_dt *, void *, gfc_charlen_type);
101 1.1 mrg export_proto(transfer_character_write);
102 1.1 mrg
103 1.1 mrg extern void transfer_character_wide (st_parameter_dt *, void *, gfc_charlen_type, int);
104 1.1 mrg export_proto(transfer_character_wide);
105 1.1 mrg
106 1.1 mrg extern void transfer_character_wide_write (st_parameter_dt *,
107 1.1 mrg void *, gfc_charlen_type, int);
108 1.1 mrg export_proto(transfer_character_wide_write);
109 1.1 mrg
110 1.1 mrg extern void transfer_complex (st_parameter_dt *, void *, int);
111 1.1 mrg export_proto(transfer_complex);
112 1.1 mrg
113 1.1 mrg extern void transfer_complex_write (st_parameter_dt *, void *, int);
114 1.1 mrg export_proto(transfer_complex_write);
115 1.1 mrg
116 1.1 mrg extern void transfer_array (st_parameter_dt *, gfc_array_char *, int,
117 1.1 mrg gfc_charlen_type);
118 1.1 mrg export_proto(transfer_array);
119 1.1 mrg
120 1.1 mrg extern void transfer_array_write (st_parameter_dt *, gfc_array_char *, int,
121 1.1 mrg gfc_charlen_type);
122 1.1 mrg export_proto(transfer_array_write);
123 1.1 mrg
124 1.1 mrg /* User defined derived type input/output. */
125 1.1 mrg extern void
126 1.1 mrg transfer_derived (st_parameter_dt *dtp, void *dtio_source, void *dtio_proc);
127 1.1 mrg export_proto(transfer_derived);
128 1.1 mrg
129 1.1 mrg extern void
130 1.1 mrg transfer_derived_write (st_parameter_dt *dtp, void *dtio_source, void *dtio_proc);
131 1.1 mrg export_proto(transfer_derived_write);
132 1.1 mrg
133 1.1 mrg static void us_read (st_parameter_dt *, int);
134 1.1 mrg static void us_write (st_parameter_dt *, int);
135 1.1 mrg static void next_record_r_unf (st_parameter_dt *, int);
136 1.1 mrg static void next_record_w_unf (st_parameter_dt *, int);
137 1.1 mrg
138 1.1 mrg static const st_option advance_opt[] = {
139 1.1 mrg {"yes", ADVANCE_YES},
140 1.1 mrg {"no", ADVANCE_NO},
141 1.1 mrg {NULL, 0}
142 1.1 mrg };
143 1.1 mrg
144 1.1 mrg
145 1.1 mrg static const st_option decimal_opt[] = {
146 1.1 mrg {"point", DECIMAL_POINT},
147 1.1 mrg {"comma", DECIMAL_COMMA},
148 1.1 mrg {NULL, 0}
149 1.1 mrg };
150 1.1 mrg
151 1.1 mrg static const st_option round_opt[] = {
152 1.1 mrg {"up", ROUND_UP},
153 1.1 mrg {"down", ROUND_DOWN},
154 1.1 mrg {"zero", ROUND_ZERO},
155 1.1 mrg {"nearest", ROUND_NEAREST},
156 1.1 mrg {"compatible", ROUND_COMPATIBLE},
157 1.1 mrg {"processor_defined", ROUND_PROCDEFINED},
158 1.1 mrg {NULL, 0}
159 1.1 mrg };
160 1.1 mrg
161 1.1 mrg
162 1.1 mrg static const st_option sign_opt[] = {
163 1.1 mrg {"plus", SIGN_SP},
164 1.1 mrg {"suppress", SIGN_SS},
165 1.1 mrg {"processor_defined", SIGN_S},
166 1.1 mrg {NULL, 0}
167 1.1 mrg };
168 1.1 mrg
169 1.1 mrg static const st_option blank_opt[] = {
170 1.1 mrg {"null", BLANK_NULL},
171 1.1 mrg {"zero", BLANK_ZERO},
172 1.1 mrg {NULL, 0}
173 1.1 mrg };
174 1.1 mrg
175 1.1 mrg static const st_option delim_opt[] = {
176 1.1 mrg {"apostrophe", DELIM_APOSTROPHE},
177 1.1 mrg {"quote", DELIM_QUOTE},
178 1.1 mrg {"none", DELIM_NONE},
179 1.1 mrg {NULL, 0}
180 1.1 mrg };
181 1.1 mrg
182 1.1 mrg static const st_option pad_opt[] = {
183 1.1 mrg {"yes", PAD_YES},
184 1.1 mrg {"no", PAD_NO},
185 1.1 mrg {NULL, 0}
186 1.1 mrg };
187 1.1 mrg
188 1.1 mrg static const st_option async_opt[] = {
189 1.1 mrg {"yes", ASYNC_YES},
190 1.1 mrg {"no", ASYNC_NO},
191 1.1 mrg {NULL, 0}
192 1.1 mrg };
193 1.1 mrg
194 1.1 mrg typedef enum
195 1.1 mrg { FORMATTED_SEQUENTIAL, UNFORMATTED_SEQUENTIAL,
196 1.1.1.2 mrg FORMATTED_DIRECT, UNFORMATTED_DIRECT, FORMATTED_STREAM,
197 1.1.1.2 mrg UNFORMATTED_STREAM, FORMATTED_UNSPECIFIED
198 1.1 mrg }
199 1.1 mrg file_mode;
200 1.1 mrg
201 1.1 mrg
202 1.1 mrg static file_mode
203 1.1 mrg current_mode (st_parameter_dt *dtp)
204 1.1 mrg {
205 1.1 mrg file_mode m;
206 1.1 mrg
207 1.1.1.2 mrg m = FORMATTED_UNSPECIFIED;
208 1.1 mrg
209 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
210 1.1 mrg {
211 1.1 mrg m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
212 1.1 mrg FORMATTED_DIRECT : UNFORMATTED_DIRECT;
213 1.1 mrg }
214 1.1 mrg else if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
215 1.1 mrg {
216 1.1 mrg m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
217 1.1 mrg FORMATTED_SEQUENTIAL : UNFORMATTED_SEQUENTIAL;
218 1.1 mrg }
219 1.1 mrg else if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
220 1.1 mrg {
221 1.1 mrg m = dtp->u.p.current_unit->flags.form == FORM_FORMATTED ?
222 1.1 mrg FORMATTED_STREAM : UNFORMATTED_STREAM;
223 1.1 mrg }
224 1.1 mrg
225 1.1 mrg return m;
226 1.1 mrg }
227 1.1 mrg
228 1.1 mrg
229 1.1 mrg /* Mid level data transfer statements. */
230 1.1 mrg
231 1.1 mrg /* Read sequential file - internal unit */
232 1.1 mrg
233 1.1 mrg static char *
234 1.1 mrg read_sf_internal (st_parameter_dt *dtp, size_t *length)
235 1.1 mrg {
236 1.1 mrg static char *empty_string[0];
237 1.1 mrg char *base = NULL;
238 1.1 mrg size_t lorig;
239 1.1 mrg
240 1.1 mrg /* Zero size array gives internal unit len of 0. Nothing to read. */
241 1.1 mrg if (dtp->internal_unit_len == 0
242 1.1 mrg && dtp->u.p.current_unit->pad_status == PAD_NO)
243 1.1 mrg hit_eof (dtp);
244 1.1 mrg
245 1.1 mrg /* There are some cases with mixed DTIO where we have read a character
246 1.1 mrg and saved it in the last character buffer, so we need to backup. */
247 1.1 mrg if (unlikely (dtp->u.p.current_unit->child_dtio > 0 &&
248 1.1 mrg dtp->u.p.current_unit->last_char != EOF - 1))
249 1.1 mrg {
250 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
251 1.1 mrg sseek (dtp->u.p.current_unit->s, -1, SEEK_CUR);
252 1.1 mrg }
253 1.1 mrg
254 1.1 mrg /* To support legacy code we have to scan the input string one byte
255 1.1 mrg at a time because we don't know where an early comma may be and the
256 1.1 mrg requested length could go past the end of a comma shortened
257 1.1 mrg string. We only do this if -std=legacy was given at compile
258 1.1 mrg time. We also do not support this on kind=4 strings. */
259 1.1 mrg if (unlikely(compile_options.warn_std == 0)) // the slow legacy way.
260 1.1 mrg {
261 1.1 mrg size_t n;
262 1.1 mrg size_t tmp = 1;
263 1.1 mrg char *q;
264 1.1 mrg
265 1.1 mrg /* If we have seen an eor previously, return a length of 0. The
266 1.1 mrg caller is responsible for correctly padding the input field. */
267 1.1 mrg if (dtp->u.p.sf_seen_eor)
268 1.1 mrg {
269 1.1 mrg *length = 0;
270 1.1 mrg /* Just return something that isn't a NULL pointer, otherwise the
271 1.1 mrg caller thinks an error occurred. */
272 1.1 mrg return (char*) empty_string;
273 1.1 mrg }
274 1.1 mrg
275 1.1 mrg /* Get the first character of the string to establish the base
276 1.1 mrg address and check for comma or end-of-record condition. */
277 1.1 mrg base = mem_alloc_r (dtp->u.p.current_unit->s, &tmp);
278 1.1 mrg if (tmp == 0)
279 1.1 mrg {
280 1.1 mrg dtp->u.p.sf_seen_eor = 1;
281 1.1 mrg *length = 0;
282 1.1 mrg return (char*) empty_string;
283 1.1 mrg }
284 1.1 mrg if (*base == ',')
285 1.1 mrg {
286 1.1 mrg dtp->u.p.current_unit->bytes_left--;
287 1.1 mrg *length = 0;
288 1.1 mrg return (char*) empty_string;
289 1.1 mrg }
290 1.1 mrg
291 1.1 mrg /* Now we scan the rest and deal with either an end-of-file
292 1.1 mrg condition or a comma, as needed. */
293 1.1 mrg for (n = 1; n < *length; n++)
294 1.1 mrg {
295 1.1 mrg q = mem_alloc_r (dtp->u.p.current_unit->s, &tmp);
296 1.1 mrg if (tmp == 0)
297 1.1 mrg {
298 1.1 mrg hit_eof (dtp);
299 1.1 mrg return NULL;
300 1.1 mrg }
301 1.1 mrg if (*q == ',')
302 1.1 mrg {
303 1.1 mrg dtp->u.p.current_unit->bytes_left -= n;
304 1.1 mrg *length = n;
305 1.1 mrg break;
306 1.1 mrg }
307 1.1 mrg }
308 1.1 mrg }
309 1.1 mrg else // the fast way
310 1.1 mrg {
311 1.1 mrg lorig = *length;
312 1.1 mrg if (is_char4_unit(dtp))
313 1.1 mrg {
314 1.1 mrg gfc_char4_t *p = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s,
315 1.1 mrg length);
316 1.1 mrg base = fbuf_alloc (dtp->u.p.current_unit, lorig);
317 1.1 mrg for (size_t i = 0; i < *length; i++, p++)
318 1.1 mrg base[i] = *p > 255 ? '?' : (unsigned char) *p;
319 1.1 mrg }
320 1.1 mrg else
321 1.1 mrg base = mem_alloc_r (dtp->u.p.current_unit->s, length);
322 1.1 mrg
323 1.1 mrg if (unlikely (lorig > *length))
324 1.1 mrg {
325 1.1 mrg hit_eof (dtp);
326 1.1 mrg return NULL;
327 1.1 mrg }
328 1.1 mrg }
329 1.1 mrg
330 1.1 mrg dtp->u.p.current_unit->bytes_left -= *length;
331 1.1 mrg
332 1.1 mrg if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
333 1.1 mrg dtp->u.p.current_unit->has_size)
334 1.1 mrg dtp->u.p.current_unit->size_used += (GFC_IO_INT) *length;
335 1.1 mrg
336 1.1 mrg return base;
337 1.1 mrg
338 1.1 mrg }
339 1.1 mrg
340 1.1 mrg /* When reading sequential formatted records we have a problem. We
341 1.1 mrg don't know how long the line is until we read the trailing newline,
342 1.1 mrg and we don't want to read too much. If we read too much, we might
343 1.1 mrg have to do a physical seek backwards depending on how much data is
344 1.1 mrg present, and devices like terminals aren't seekable and would cause
345 1.1 mrg an I/O error.
346 1.1 mrg
347 1.1 mrg Given this, the solution is to read a byte at a time, stopping if
348 1.1 mrg we hit the newline. For small allocations, we use a static buffer.
349 1.1 mrg For larger allocations, we are forced to allocate memory on the
350 1.1 mrg heap. Hopefully this won't happen very often. */
351 1.1 mrg
352 1.1 mrg /* Read sequential file - external unit */
353 1.1 mrg
354 1.1 mrg static char *
355 1.1 mrg read_sf (st_parameter_dt *dtp, size_t *length)
356 1.1 mrg {
357 1.1 mrg static char *empty_string[0];
358 1.1 mrg size_t lorig, n;
359 1.1 mrg int q, q2;
360 1.1 mrg int seen_comma;
361 1.1 mrg
362 1.1 mrg /* If we have seen an eor previously, return a length of 0. The
363 1.1 mrg caller is responsible for correctly padding the input field. */
364 1.1 mrg if (dtp->u.p.sf_seen_eor)
365 1.1 mrg {
366 1.1 mrg *length = 0;
367 1.1 mrg /* Just return something that isn't a NULL pointer, otherwise the
368 1.1 mrg caller thinks an error occurred. */
369 1.1 mrg return (char*) empty_string;
370 1.1 mrg }
371 1.1 mrg
372 1.1 mrg /* There are some cases with mixed DTIO where we have read a character
373 1.1 mrg and saved it in the last character buffer, so we need to backup. */
374 1.1 mrg if (unlikely (dtp->u.p.current_unit->child_dtio > 0 &&
375 1.1 mrg dtp->u.p.current_unit->last_char != EOF - 1))
376 1.1 mrg {
377 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
378 1.1 mrg fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
379 1.1 mrg }
380 1.1 mrg
381 1.1 mrg n = seen_comma = 0;
382 1.1 mrg
383 1.1 mrg /* Read data into format buffer and scan through it. */
384 1.1 mrg lorig = *length;
385 1.1 mrg
386 1.1 mrg while (n < *length)
387 1.1 mrg {
388 1.1 mrg q = fbuf_getc (dtp->u.p.current_unit);
389 1.1 mrg if (q == EOF)
390 1.1 mrg break;
391 1.1 mrg else if (dtp->u.p.current_unit->flags.cc != CC_NONE
392 1.1 mrg && (q == '\n' || q == '\r'))
393 1.1 mrg {
394 1.1 mrg /* Unexpected end of line. Set the position. */
395 1.1 mrg dtp->u.p.sf_seen_eor = 1;
396 1.1 mrg
397 1.1 mrg /* If we see an EOR during non-advancing I/O, we need to skip
398 1.1 mrg the rest of the I/O statement. Set the corresponding flag. */
399 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO || dtp->u.p.seen_dollar)
400 1.1 mrg dtp->u.p.eor_condition = 1;
401 1.1 mrg
402 1.1 mrg /* If we encounter a CR, it might be a CRLF. */
403 1.1 mrg if (q == '\r') /* Probably a CRLF */
404 1.1 mrg {
405 1.1 mrg /* See if there is an LF. */
406 1.1 mrg q2 = fbuf_getc (dtp->u.p.current_unit);
407 1.1 mrg if (q2 == '\n')
408 1.1 mrg dtp->u.p.sf_seen_eor = 2;
409 1.1 mrg else if (q2 != EOF) /* Oops, seek back. */
410 1.1 mrg fbuf_seek (dtp->u.p.current_unit, -1, SEEK_CUR);
411 1.1 mrg }
412 1.1 mrg
413 1.1 mrg /* Without padding, terminate the I/O statement without assigning
414 1.1 mrg the value. With padding, the value still needs to be assigned,
415 1.1 mrg so we can just continue with a short read. */
416 1.1 mrg if (dtp->u.p.current_unit->pad_status == PAD_NO)
417 1.1 mrg {
418 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
419 1.1 mrg return NULL;
420 1.1 mrg }
421 1.1 mrg
422 1.1 mrg *length = n;
423 1.1 mrg goto done;
424 1.1 mrg }
425 1.1 mrg /* Short circuit the read if a comma is found during numeric input.
426 1.1 mrg The flag is set to zero during character reads so that commas in
427 1.1 mrg strings are not ignored */
428 1.1 mrg else if (q == ',')
429 1.1 mrg if (dtp->u.p.sf_read_comma == 1)
430 1.1 mrg {
431 1.1 mrg seen_comma = 1;
432 1.1 mrg notify_std (&dtp->common, GFC_STD_GNU,
433 1.1 mrg "Comma in formatted numeric read.");
434 1.1 mrg break;
435 1.1 mrg }
436 1.1 mrg n++;
437 1.1 mrg }
438 1.1 mrg
439 1.1 mrg *length = n;
440 1.1 mrg
441 1.1 mrg /* A short read implies we hit EOF, unless we hit EOR, a comma, or
442 1.1 mrg some other stuff. Set the relevant flags. */
443 1.1 mrg if (lorig > *length && !dtp->u.p.sf_seen_eor && !seen_comma)
444 1.1 mrg {
445 1.1 mrg if (n > 0)
446 1.1 mrg {
447 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO)
448 1.1 mrg {
449 1.1 mrg if (dtp->u.p.current_unit->pad_status == PAD_NO)
450 1.1 mrg {
451 1.1 mrg hit_eof (dtp);
452 1.1 mrg return NULL;
453 1.1 mrg }
454 1.1 mrg else
455 1.1 mrg dtp->u.p.eor_condition = 1;
456 1.1 mrg }
457 1.1 mrg else
458 1.1 mrg dtp->u.p.at_eof = 1;
459 1.1 mrg }
460 1.1 mrg else if (dtp->u.p.advance_status == ADVANCE_NO
461 1.1 mrg || dtp->u.p.current_unit->pad_status == PAD_NO
462 1.1 mrg || dtp->u.p.current_unit->bytes_left
463 1.1 mrg == dtp->u.p.current_unit->recl)
464 1.1 mrg {
465 1.1 mrg hit_eof (dtp);
466 1.1 mrg return NULL;
467 1.1 mrg }
468 1.1 mrg }
469 1.1 mrg
470 1.1 mrg done:
471 1.1 mrg
472 1.1 mrg dtp->u.p.current_unit->bytes_left -= n;
473 1.1 mrg
474 1.1 mrg if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
475 1.1 mrg dtp->u.p.current_unit->has_size)
476 1.1 mrg dtp->u.p.current_unit->size_used += (GFC_IO_INT) n;
477 1.1 mrg
478 1.1 mrg /* We can't call fbuf_getptr before the loop doing fbuf_getc, because
479 1.1 mrg fbuf_getc might reallocate the buffer. So return current pointer
480 1.1 mrg minus all the advances, which is n plus up to two characters
481 1.1 mrg of newline or comma. */
482 1.1 mrg return fbuf_getptr (dtp->u.p.current_unit)
483 1.1 mrg - n - dtp->u.p.sf_seen_eor - seen_comma;
484 1.1 mrg }
485 1.1 mrg
486 1.1 mrg
487 1.1 mrg /* Function for reading the next couple of bytes from the current
488 1.1 mrg file, advancing the current position. We return NULL on end of record or
489 1.1 mrg end of file. This function is only for formatted I/O, unformatted uses
490 1.1 mrg read_block_direct.
491 1.1 mrg
492 1.1 mrg If the read is short, then it is because the current record does not
493 1.1 mrg have enough data to satisfy the read request and the file was
494 1.1.1.3 mrg opened with PAD=YES. The caller must assume trailing spaces for
495 1.1 mrg short reads. */
496 1.1 mrg
497 1.1 mrg void *
498 1.1 mrg read_block_form (st_parameter_dt *dtp, size_t *nbytes)
499 1.1 mrg {
500 1.1 mrg char *source;
501 1.1 mrg size_t norig;
502 1.1 mrg
503 1.1 mrg if (!is_stream_io (dtp))
504 1.1 mrg {
505 1.1 mrg if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
506 1.1 mrg {
507 1.1 mrg /* For preconnected units with default record length, set bytes left
508 1.1 mrg to unit record length and proceed, otherwise error. */
509 1.1 mrg if (dtp->u.p.current_unit->unit_number == options.stdin_unit
510 1.1 mrg && dtp->u.p.current_unit->recl == default_recl)
511 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
512 1.1 mrg else
513 1.1 mrg {
514 1.1 mrg if (unlikely (dtp->u.p.current_unit->pad_status == PAD_NO)
515 1.1 mrg && !is_internal_unit (dtp))
516 1.1 mrg {
517 1.1 mrg /* Not enough data left. */
518 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
519 1.1 mrg return NULL;
520 1.1 mrg }
521 1.1 mrg }
522 1.1 mrg
523 1.1 mrg if (is_internal_unit(dtp))
524 1.1 mrg {
525 1.1 mrg if (*nbytes > 0 && dtp->u.p.current_unit->bytes_left == 0)
526 1.1 mrg {
527 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO)
528 1.1 mrg {
529 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
530 1.1 mrg return NULL;
531 1.1 mrg }
532 1.1 mrg }
533 1.1 mrg }
534 1.1 mrg else
535 1.1 mrg {
536 1.1 mrg if (unlikely (dtp->u.p.current_unit->bytes_left == 0))
537 1.1 mrg {
538 1.1 mrg hit_eof (dtp);
539 1.1 mrg return NULL;
540 1.1 mrg }
541 1.1 mrg }
542 1.1 mrg
543 1.1 mrg *nbytes = dtp->u.p.current_unit->bytes_left;
544 1.1 mrg }
545 1.1 mrg }
546 1.1 mrg
547 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
548 1.1 mrg (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL ||
549 1.1 mrg dtp->u.p.current_unit->flags.access == ACCESS_STREAM))
550 1.1 mrg {
551 1.1 mrg if (is_internal_unit (dtp))
552 1.1 mrg source = read_sf_internal (dtp, nbytes);
553 1.1 mrg else
554 1.1 mrg source = read_sf (dtp, nbytes);
555 1.1 mrg
556 1.1 mrg dtp->u.p.current_unit->strm_pos +=
557 1.1 mrg (gfc_offset) (*nbytes + dtp->u.p.sf_seen_eor);
558 1.1 mrg return source;
559 1.1 mrg }
560 1.1 mrg
561 1.1 mrg /* If we reach here, we can assume it's direct access. */
562 1.1 mrg
563 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) *nbytes;
564 1.1 mrg
565 1.1 mrg norig = *nbytes;
566 1.1 mrg source = fbuf_read (dtp->u.p.current_unit, nbytes);
567 1.1 mrg fbuf_seek (dtp->u.p.current_unit, *nbytes, SEEK_CUR);
568 1.1 mrg
569 1.1 mrg if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
570 1.1 mrg dtp->u.p.current_unit->has_size)
571 1.1 mrg dtp->u.p.current_unit->size_used += (GFC_IO_INT) *nbytes;
572 1.1 mrg
573 1.1 mrg if (norig != *nbytes)
574 1.1 mrg {
575 1.1 mrg /* Short read, this shouldn't happen. */
576 1.1 mrg if (dtp->u.p.current_unit->pad_status == PAD_NO)
577 1.1 mrg {
578 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
579 1.1 mrg source = NULL;
580 1.1 mrg }
581 1.1 mrg }
582 1.1 mrg
583 1.1 mrg dtp->u.p.current_unit->strm_pos += (gfc_offset) *nbytes;
584 1.1 mrg
585 1.1 mrg return source;
586 1.1 mrg }
587 1.1 mrg
588 1.1 mrg
589 1.1 mrg /* Read a block from a character(kind=4) internal unit, to be transferred into
590 1.1 mrg a character(kind=4) variable. Note: Portions of this code borrowed from
591 1.1 mrg read_sf_internal. */
592 1.1 mrg void *
593 1.1 mrg read_block_form4 (st_parameter_dt *dtp, size_t *nbytes)
594 1.1 mrg {
595 1.1 mrg static gfc_char4_t *empty_string[0];
596 1.1 mrg gfc_char4_t *source;
597 1.1 mrg size_t lorig;
598 1.1 mrg
599 1.1 mrg if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
600 1.1 mrg *nbytes = dtp->u.p.current_unit->bytes_left;
601 1.1 mrg
602 1.1 mrg /* Zero size array gives internal unit len of 0. Nothing to read. */
603 1.1 mrg if (dtp->internal_unit_len == 0
604 1.1 mrg && dtp->u.p.current_unit->pad_status == PAD_NO)
605 1.1 mrg hit_eof (dtp);
606 1.1 mrg
607 1.1 mrg /* If we have seen an eor previously, return a length of 0. The
608 1.1 mrg caller is responsible for correctly padding the input field. */
609 1.1 mrg if (dtp->u.p.sf_seen_eor)
610 1.1 mrg {
611 1.1 mrg *nbytes = 0;
612 1.1 mrg /* Just return something that isn't a NULL pointer, otherwise the
613 1.1 mrg caller thinks an error occurred. */
614 1.1 mrg return empty_string;
615 1.1 mrg }
616 1.1 mrg
617 1.1 mrg lorig = *nbytes;
618 1.1 mrg source = (gfc_char4_t *) mem_alloc_r4 (dtp->u.p.current_unit->s, nbytes);
619 1.1 mrg
620 1.1 mrg if (unlikely (lorig > *nbytes))
621 1.1 mrg {
622 1.1 mrg hit_eof (dtp);
623 1.1 mrg return NULL;
624 1.1 mrg }
625 1.1 mrg
626 1.1 mrg dtp->u.p.current_unit->bytes_left -= *nbytes;
627 1.1 mrg
628 1.1 mrg if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
629 1.1 mrg dtp->u.p.current_unit->has_size)
630 1.1 mrg dtp->u.p.current_unit->size_used += (GFC_IO_INT) *nbytes;
631 1.1 mrg
632 1.1 mrg return source;
633 1.1 mrg }
634 1.1 mrg
635 1.1 mrg
636 1.1 mrg /* Reads a block directly into application data space. This is for
637 1.1 mrg unformatted files. */
638 1.1 mrg
639 1.1 mrg static void
640 1.1 mrg read_block_direct (st_parameter_dt *dtp, void *buf, size_t nbytes)
641 1.1 mrg {
642 1.1 mrg ssize_t to_read_record;
643 1.1 mrg ssize_t have_read_record;
644 1.1 mrg ssize_t to_read_subrecord;
645 1.1 mrg ssize_t have_read_subrecord;
646 1.1 mrg int short_record;
647 1.1 mrg
648 1.1 mrg if (is_stream_io (dtp))
649 1.1 mrg {
650 1.1 mrg have_read_record = sread (dtp->u.p.current_unit->s, buf,
651 1.1 mrg nbytes);
652 1.1 mrg if (unlikely (have_read_record < 0))
653 1.1 mrg {
654 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
655 1.1 mrg return;
656 1.1 mrg }
657 1.1 mrg
658 1.1 mrg dtp->u.p.current_unit->strm_pos += (gfc_offset) have_read_record;
659 1.1 mrg
660 1.1 mrg if (unlikely ((ssize_t) nbytes != have_read_record))
661 1.1 mrg {
662 1.1 mrg /* Short read, e.g. if we hit EOF. For stream files,
663 1.1 mrg we have to set the end-of-file condition. */
664 1.1 mrg hit_eof (dtp);
665 1.1 mrg }
666 1.1 mrg return;
667 1.1 mrg }
668 1.1 mrg
669 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
670 1.1 mrg {
671 1.1 mrg if (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes)
672 1.1 mrg {
673 1.1 mrg short_record = 1;
674 1.1 mrg to_read_record = dtp->u.p.current_unit->bytes_left;
675 1.1 mrg nbytes = to_read_record;
676 1.1 mrg }
677 1.1 mrg else
678 1.1 mrg {
679 1.1 mrg short_record = 0;
680 1.1 mrg to_read_record = nbytes;
681 1.1 mrg }
682 1.1 mrg
683 1.1 mrg dtp->u.p.current_unit->bytes_left -= to_read_record;
684 1.1 mrg
685 1.1 mrg to_read_record = sread (dtp->u.p.current_unit->s, buf, to_read_record);
686 1.1 mrg if (unlikely (to_read_record < 0))
687 1.1 mrg {
688 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
689 1.1 mrg return;
690 1.1 mrg }
691 1.1 mrg
692 1.1 mrg if (to_read_record != (ssize_t) nbytes)
693 1.1 mrg {
694 1.1 mrg /* Short read, e.g. if we hit EOF. Apparently, we read
695 1.1 mrg more than was written to the last record. */
696 1.1 mrg return;
697 1.1 mrg }
698 1.1 mrg
699 1.1 mrg if (unlikely (short_record))
700 1.1 mrg {
701 1.1 mrg generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
702 1.1 mrg }
703 1.1 mrg return;
704 1.1 mrg }
705 1.1 mrg
706 1.1 mrg /* Unformatted sequential. We loop over the subrecords, reading
707 1.1 mrg until the request has been fulfilled or the record has run out
708 1.1 mrg of continuation subrecords. */
709 1.1 mrg
710 1.1 mrg /* Check whether we exceed the total record length. */
711 1.1 mrg
712 1.1 mrg if (dtp->u.p.current_unit->flags.has_recl
713 1.1 mrg && ((gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left))
714 1.1 mrg {
715 1.1 mrg to_read_record = dtp->u.p.current_unit->bytes_left;
716 1.1 mrg short_record = 1;
717 1.1 mrg }
718 1.1 mrg else
719 1.1 mrg {
720 1.1 mrg to_read_record = nbytes;
721 1.1 mrg short_record = 0;
722 1.1 mrg }
723 1.1 mrg have_read_record = 0;
724 1.1 mrg
725 1.1 mrg while(1)
726 1.1 mrg {
727 1.1 mrg if (dtp->u.p.current_unit->bytes_left_subrecord
728 1.1 mrg < (gfc_offset) to_read_record)
729 1.1 mrg {
730 1.1 mrg to_read_subrecord = dtp->u.p.current_unit->bytes_left_subrecord;
731 1.1 mrg to_read_record -= to_read_subrecord;
732 1.1 mrg }
733 1.1 mrg else
734 1.1 mrg {
735 1.1 mrg to_read_subrecord = to_read_record;
736 1.1 mrg to_read_record = 0;
737 1.1 mrg }
738 1.1 mrg
739 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord -= to_read_subrecord;
740 1.1 mrg
741 1.1 mrg have_read_subrecord = sread (dtp->u.p.current_unit->s,
742 1.1 mrg buf + have_read_record, to_read_subrecord);
743 1.1 mrg if (unlikely (have_read_subrecord < 0))
744 1.1 mrg {
745 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
746 1.1 mrg return;
747 1.1 mrg }
748 1.1 mrg
749 1.1 mrg have_read_record += have_read_subrecord;
750 1.1 mrg
751 1.1 mrg if (unlikely (to_read_subrecord != have_read_subrecord))
752 1.1 mrg {
753 1.1 mrg /* Short read, e.g. if we hit EOF. This means the record
754 1.1 mrg structure has been corrupted, or the trailing record
755 1.1 mrg marker would still be present. */
756 1.1 mrg
757 1.1 mrg generate_error (&dtp->common, LIBERROR_CORRUPT_FILE, NULL);
758 1.1 mrg return;
759 1.1 mrg }
760 1.1 mrg
761 1.1 mrg if (to_read_record > 0)
762 1.1 mrg {
763 1.1 mrg if (likely (dtp->u.p.current_unit->continued))
764 1.1 mrg {
765 1.1 mrg next_record_r_unf (dtp, 0);
766 1.1 mrg us_read (dtp, 1);
767 1.1 mrg }
768 1.1 mrg else
769 1.1 mrg {
770 1.1 mrg /* Let's make sure the file position is correctly pre-positioned
771 1.1 mrg for the next read statement. */
772 1.1 mrg
773 1.1 mrg dtp->u.p.current_unit->current_record = 0;
774 1.1 mrg next_record_r_unf (dtp, 0);
775 1.1 mrg generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
776 1.1 mrg return;
777 1.1 mrg }
778 1.1 mrg }
779 1.1 mrg else
780 1.1 mrg {
781 1.1 mrg /* Normal exit, the read request has been fulfilled. */
782 1.1 mrg break;
783 1.1 mrg }
784 1.1 mrg }
785 1.1 mrg
786 1.1 mrg dtp->u.p.current_unit->bytes_left -= have_read_record;
787 1.1 mrg if (unlikely (short_record))
788 1.1 mrg {
789 1.1 mrg generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
790 1.1 mrg return;
791 1.1 mrg }
792 1.1 mrg return;
793 1.1 mrg }
794 1.1 mrg
795 1.1 mrg
796 1.1 mrg /* Function for writing a block of bytes to the current file at the
797 1.1 mrg current position, advancing the file pointer. We are given a length
798 1.1 mrg and return a pointer to a buffer that the caller must (completely)
799 1.1 mrg fill in. Returns NULL on error. */
800 1.1 mrg
801 1.1 mrg void *
802 1.1 mrg write_block (st_parameter_dt *dtp, size_t length)
803 1.1 mrg {
804 1.1 mrg char *dest;
805 1.1 mrg
806 1.1 mrg if (!is_stream_io (dtp))
807 1.1 mrg {
808 1.1 mrg if (dtp->u.p.current_unit->bytes_left < (gfc_offset) length)
809 1.1 mrg {
810 1.1 mrg /* For preconnected units with default record length, set bytes left
811 1.1 mrg to unit record length and proceed, otherwise error. */
812 1.1 mrg if (likely ((dtp->u.p.current_unit->unit_number
813 1.1 mrg == options.stdout_unit
814 1.1 mrg || dtp->u.p.current_unit->unit_number
815 1.1 mrg == options.stderr_unit)
816 1.1 mrg && dtp->u.p.current_unit->recl == default_recl))
817 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
818 1.1 mrg else
819 1.1 mrg {
820 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
821 1.1 mrg return NULL;
822 1.1 mrg }
823 1.1 mrg }
824 1.1 mrg
825 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) length;
826 1.1 mrg }
827 1.1 mrg
828 1.1 mrg if (is_internal_unit (dtp))
829 1.1 mrg {
830 1.1 mrg if (is_char4_unit(dtp)) /* char4 internel unit. */
831 1.1 mrg {
832 1.1 mrg gfc_char4_t *dest4;
833 1.1 mrg dest4 = mem_alloc_w4 (dtp->u.p.current_unit->s, &length);
834 1.1 mrg if (dest4 == NULL)
835 1.1 mrg {
836 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
837 1.1 mrg return NULL;
838 1.1 mrg }
839 1.1 mrg return dest4;
840 1.1 mrg }
841 1.1 mrg else
842 1.1 mrg dest = mem_alloc_w (dtp->u.p.current_unit->s, &length);
843 1.1 mrg
844 1.1 mrg if (dest == NULL)
845 1.1 mrg {
846 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
847 1.1 mrg return NULL;
848 1.1 mrg }
849 1.1 mrg
850 1.1 mrg if (unlikely (dtp->u.p.current_unit->endfile == AT_ENDFILE))
851 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
852 1.1 mrg }
853 1.1 mrg else
854 1.1 mrg {
855 1.1 mrg dest = fbuf_alloc (dtp->u.p.current_unit, length);
856 1.1 mrg if (dest == NULL)
857 1.1 mrg {
858 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
859 1.1 mrg return NULL;
860 1.1 mrg }
861 1.1 mrg }
862 1.1 mrg
863 1.1 mrg if (((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) ||
864 1.1 mrg dtp->u.p.current_unit->has_size)
865 1.1 mrg dtp->u.p.current_unit->size_used += (GFC_IO_INT) length;
866 1.1 mrg
867 1.1 mrg dtp->u.p.current_unit->strm_pos += (gfc_offset) length;
868 1.1 mrg
869 1.1 mrg return dest;
870 1.1 mrg }
871 1.1 mrg
872 1.1 mrg
873 1.1 mrg /* High level interface to swrite(), taking care of errors. This is only
874 1.1 mrg called for unformatted files. There are three cases to consider:
875 1.1 mrg Stream I/O, unformatted direct, unformatted sequential. */
876 1.1 mrg
877 1.1 mrg static bool
878 1.1 mrg write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
879 1.1 mrg {
880 1.1 mrg
881 1.1 mrg ssize_t have_written;
882 1.1 mrg ssize_t to_write_subrecord;
883 1.1 mrg int short_record;
884 1.1 mrg
885 1.1 mrg /* Stream I/O. */
886 1.1 mrg
887 1.1 mrg if (is_stream_io (dtp))
888 1.1 mrg {
889 1.1 mrg have_written = swrite (dtp->u.p.current_unit->s, buf, nbytes);
890 1.1 mrg if (unlikely (have_written < 0))
891 1.1 mrg {
892 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
893 1.1 mrg return false;
894 1.1 mrg }
895 1.1 mrg
896 1.1 mrg dtp->u.p.current_unit->strm_pos += (gfc_offset) have_written;
897 1.1 mrg
898 1.1 mrg return true;
899 1.1 mrg }
900 1.1 mrg
901 1.1 mrg /* Unformatted direct access. */
902 1.1 mrg
903 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
904 1.1 mrg {
905 1.1 mrg if (unlikely (dtp->u.p.current_unit->bytes_left < (gfc_offset) nbytes))
906 1.1 mrg {
907 1.1 mrg generate_error (&dtp->common, LIBERROR_DIRECT_EOR, NULL);
908 1.1 mrg return false;
909 1.1 mrg }
910 1.1 mrg
911 1.1 mrg if (buf == NULL && nbytes == 0)
912 1.1 mrg return true;
913 1.1 mrg
914 1.1 mrg have_written = swrite (dtp->u.p.current_unit->s, buf, nbytes);
915 1.1 mrg if (unlikely (have_written < 0))
916 1.1 mrg {
917 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
918 1.1 mrg return false;
919 1.1 mrg }
920 1.1 mrg
921 1.1 mrg dtp->u.p.current_unit->strm_pos += (gfc_offset) have_written;
922 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) have_written;
923 1.1 mrg
924 1.1 mrg return true;
925 1.1 mrg }
926 1.1 mrg
927 1.1 mrg /* Unformatted sequential. */
928 1.1 mrg
929 1.1 mrg have_written = 0;
930 1.1 mrg
931 1.1 mrg if (dtp->u.p.current_unit->flags.has_recl
932 1.1 mrg && (gfc_offset) nbytes > dtp->u.p.current_unit->bytes_left)
933 1.1 mrg {
934 1.1 mrg nbytes = dtp->u.p.current_unit->bytes_left;
935 1.1 mrg short_record = 1;
936 1.1 mrg }
937 1.1 mrg else
938 1.1 mrg {
939 1.1 mrg short_record = 0;
940 1.1 mrg }
941 1.1 mrg
942 1.1 mrg while (1)
943 1.1 mrg {
944 1.1 mrg
945 1.1 mrg to_write_subrecord =
946 1.1 mrg (size_t) dtp->u.p.current_unit->bytes_left_subrecord < nbytes ?
947 1.1 mrg (size_t) dtp->u.p.current_unit->bytes_left_subrecord : nbytes;
948 1.1 mrg
949 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord -=
950 1.1 mrg (gfc_offset) to_write_subrecord;
951 1.1 mrg
952 1.1 mrg to_write_subrecord = swrite (dtp->u.p.current_unit->s,
953 1.1 mrg buf + have_written, to_write_subrecord);
954 1.1 mrg if (unlikely (to_write_subrecord < 0))
955 1.1 mrg {
956 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
957 1.1 mrg return false;
958 1.1 mrg }
959 1.1 mrg
960 1.1 mrg dtp->u.p.current_unit->strm_pos += (gfc_offset) to_write_subrecord;
961 1.1 mrg nbytes -= to_write_subrecord;
962 1.1 mrg have_written += to_write_subrecord;
963 1.1 mrg
964 1.1 mrg if (nbytes == 0)
965 1.1 mrg break;
966 1.1 mrg
967 1.1 mrg next_record_w_unf (dtp, 1);
968 1.1 mrg us_write (dtp, 1);
969 1.1 mrg }
970 1.1 mrg dtp->u.p.current_unit->bytes_left -= have_written;
971 1.1 mrg if (unlikely (short_record))
972 1.1 mrg {
973 1.1 mrg generate_error (&dtp->common, LIBERROR_SHORT_RECORD, NULL);
974 1.1 mrg return false;
975 1.1 mrg }
976 1.1 mrg return true;
977 1.1 mrg }
978 1.1 mrg
979 1.1 mrg
980 1.1 mrg /* Reverse memcpy - used for byte swapping. */
981 1.1 mrg
982 1.1 mrg static void
983 1.1 mrg reverse_memcpy (void *dest, const void *src, size_t n)
984 1.1 mrg {
985 1.1 mrg char *d, *s;
986 1.1 mrg size_t i;
987 1.1 mrg
988 1.1 mrg d = (char *) dest;
989 1.1 mrg s = (char *) src + n - 1;
990 1.1 mrg
991 1.1 mrg /* Write with ascending order - this is likely faster
992 1.1 mrg on modern architectures because of write combining. */
993 1.1 mrg for (i=0; i<n; i++)
994 1.1 mrg *(d++) = *(s--);
995 1.1 mrg }
996 1.1 mrg
997 1.1 mrg
998 1.1 mrg /* Utility function for byteswapping an array, using the bswap
999 1.1 mrg builtins if possible. dest and src can overlap completely, or then
1000 1.1 mrg they must point to separate objects; partial overlaps are not
1001 1.1 mrg allowed. */
1002 1.1 mrg
1003 1.1 mrg static void
1004 1.1 mrg bswap_array (void *dest, const void *src, size_t size, size_t nelems)
1005 1.1 mrg {
1006 1.1 mrg const char *ps;
1007 1.1 mrg char *pd;
1008 1.1 mrg
1009 1.1 mrg switch (size)
1010 1.1 mrg {
1011 1.1 mrg case 1:
1012 1.1 mrg break;
1013 1.1 mrg case 2:
1014 1.1 mrg for (size_t i = 0; i < nelems; i++)
1015 1.1 mrg ((uint16_t*)dest)[i] = __builtin_bswap16 (((uint16_t*)src)[i]);
1016 1.1 mrg break;
1017 1.1 mrg case 4:
1018 1.1 mrg for (size_t i = 0; i < nelems; i++)
1019 1.1 mrg ((uint32_t*)dest)[i] = __builtin_bswap32 (((uint32_t*)src)[i]);
1020 1.1 mrg break;
1021 1.1 mrg case 8:
1022 1.1 mrg for (size_t i = 0; i < nelems; i++)
1023 1.1 mrg ((uint64_t*)dest)[i] = __builtin_bswap64 (((uint64_t*)src)[i]);
1024 1.1 mrg break;
1025 1.1 mrg case 12:
1026 1.1 mrg ps = src;
1027 1.1 mrg pd = dest;
1028 1.1 mrg for (size_t i = 0; i < nelems; i++)
1029 1.1 mrg {
1030 1.1 mrg uint32_t tmp;
1031 1.1 mrg memcpy (&tmp, ps, 4);
1032 1.1 mrg *(uint32_t*)pd = __builtin_bswap32 (*(uint32_t*)(ps + 8));
1033 1.1 mrg *(uint32_t*)(pd + 4) = __builtin_bswap32 (*(uint32_t*)(ps + 4));
1034 1.1 mrg *(uint32_t*)(pd + 8) = __builtin_bswap32 (tmp);
1035 1.1 mrg ps += size;
1036 1.1 mrg pd += size;
1037 1.1 mrg }
1038 1.1 mrg break;
1039 1.1 mrg case 16:
1040 1.1 mrg ps = src;
1041 1.1 mrg pd = dest;
1042 1.1 mrg for (size_t i = 0; i < nelems; i++)
1043 1.1 mrg {
1044 1.1 mrg uint64_t tmp;
1045 1.1 mrg memcpy (&tmp, ps, 8);
1046 1.1 mrg *(uint64_t*)pd = __builtin_bswap64 (*(uint64_t*)(ps + 8));
1047 1.1 mrg *(uint64_t*)(pd + 8) = __builtin_bswap64 (tmp);
1048 1.1 mrg ps += size;
1049 1.1 mrg pd += size;
1050 1.1 mrg }
1051 1.1 mrg break;
1052 1.1 mrg default:
1053 1.1 mrg pd = dest;
1054 1.1 mrg if (dest != src)
1055 1.1 mrg {
1056 1.1 mrg ps = src;
1057 1.1 mrg for (size_t i = 0; i < nelems; i++)
1058 1.1 mrg {
1059 1.1 mrg reverse_memcpy (pd, ps, size);
1060 1.1 mrg ps += size;
1061 1.1 mrg pd += size;
1062 1.1 mrg }
1063 1.1 mrg }
1064 1.1 mrg else
1065 1.1 mrg {
1066 1.1 mrg /* In-place byte swap. */
1067 1.1 mrg for (size_t i = 0; i < nelems; i++)
1068 1.1 mrg {
1069 1.1 mrg char tmp, *low = pd, *high = pd + size - 1;
1070 1.1 mrg for (size_t j = 0; j < size/2; j++)
1071 1.1 mrg {
1072 1.1 mrg tmp = *low;
1073 1.1 mrg *low = *high;
1074 1.1 mrg *high = tmp;
1075 1.1 mrg low++;
1076 1.1 mrg high--;
1077 1.1 mrg }
1078 1.1 mrg pd += size;
1079 1.1 mrg }
1080 1.1 mrg }
1081 1.1 mrg }
1082 1.1 mrg }
1083 1.1 mrg
1084 1.1 mrg
1085 1.1 mrg /* Master function for unformatted reads. */
1086 1.1 mrg
1087 1.1 mrg static void
1088 1.1 mrg unformatted_read (st_parameter_dt *dtp, bt type,
1089 1.1 mrg void *dest, int kind, size_t size, size_t nelems)
1090 1.1 mrg {
1091 1.1.1.3 mrg unit_convert convert;
1092 1.1.1.3 mrg
1093 1.1 mrg if (type == BT_CLASS)
1094 1.1 mrg {
1095 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
1096 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
1097 1.1 mrg char *child_iomsg;
1098 1.1 mrg gfc_charlen_type child_iomsg_len;
1099 1.1 mrg int noiostat;
1100 1.1 mrg int *child_iostat = NULL;
1101 1.1 mrg
1102 1.1 mrg /* Set iostat, intent(out). */
1103 1.1 mrg noiostat = 0;
1104 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1105 1.1 mrg dtp->common.iostat : &noiostat;
1106 1.1 mrg
1107 1.1 mrg /* Set iomsg, intent(inout). */
1108 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
1109 1.1 mrg {
1110 1.1 mrg child_iomsg = dtp->common.iomsg;
1111 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
1112 1.1 mrg }
1113 1.1 mrg else
1114 1.1 mrg {
1115 1.1 mrg child_iomsg = tmp_iomsg;
1116 1.1 mrg child_iomsg_len = IOMSG_LEN;
1117 1.1 mrg }
1118 1.1 mrg
1119 1.1 mrg /* Call the user defined unformatted READ procedure. */
1120 1.1 mrg dtp->u.p.current_unit->child_dtio++;
1121 1.1 mrg dtp->u.p.ufdtio_ptr (dest, &unit, child_iostat, child_iomsg,
1122 1.1 mrg child_iomsg_len);
1123 1.1 mrg dtp->u.p.current_unit->child_dtio--;
1124 1.1 mrg return;
1125 1.1 mrg }
1126 1.1 mrg
1127 1.1 mrg if (type == BT_CHARACTER)
1128 1.1 mrg size *= GFC_SIZE_OF_CHAR_KIND(kind);
1129 1.1 mrg read_block_direct (dtp, dest, size * nelems);
1130 1.1 mrg
1131 1.1.1.3 mrg convert = dtp->u.p.current_unit->flags.convert;
1132 1.1.1.3 mrg if (unlikely (convert != GFC_CONVERT_NATIVE) && kind != 1)
1133 1.1 mrg {
1134 1.1 mrg /* Handle wide chracters. */
1135 1.1 mrg if (type == BT_CHARACTER)
1136 1.1 mrg {
1137 1.1 mrg nelems *= size;
1138 1.1 mrg size = kind;
1139 1.1 mrg }
1140 1.1 mrg
1141 1.1 mrg /* Break up complex into its constituent reals. */
1142 1.1 mrg else if (type == BT_COMPLEX)
1143 1.1 mrg {
1144 1.1 mrg nelems *= 2;
1145 1.1 mrg size /= 2;
1146 1.1 mrg }
1147 1.1.1.3 mrg #ifndef HAVE_GFC_REAL_17
1148 1.1.1.3 mrg #if defined(HAVE_GFC_REAL_16) && GFC_REAL_16_DIGITS == 106
1149 1.1.1.3 mrg /* IBM extended format is stored as a pair of IEEE754
1150 1.1.1.3 mrg double values, with the more significant value first
1151 1.1.1.3 mrg in both big and little endian. */
1152 1.1.1.3 mrg if (kind == 16 && (type == BT_REAL || type == BT_COMPLEX))
1153 1.1.1.3 mrg {
1154 1.1.1.3 mrg nelems *= 2;
1155 1.1.1.3 mrg size /= 2;
1156 1.1.1.3 mrg }
1157 1.1.1.3 mrg #endif
1158 1.1 mrg bswap_array (dest, dest, size, nelems);
1159 1.1.1.3 mrg #else
1160 1.1.1.3 mrg unit_convert bswap = convert & ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
1161 1.1.1.3 mrg if (bswap == GFC_CONVERT_SWAP)
1162 1.1.1.3 mrg {
1163 1.1.1.3 mrg if ((type == BT_REAL || type == BT_COMPLEX)
1164 1.1.1.3 mrg && ((kind == 16 && (convert & GFC_CONVERT_R16_IEEE) == 0)
1165 1.1.1.3 mrg || (kind == 17 && (convert & GFC_CONVERT_R16_IBM))))
1166 1.1.1.3 mrg bswap_array (dest, dest, size / 2, nelems * 2);
1167 1.1.1.3 mrg else
1168 1.1.1.3 mrg bswap_array (dest, dest, size, nelems);
1169 1.1.1.3 mrg }
1170 1.1.1.3 mrg
1171 1.1.1.3 mrg if ((convert & GFC_CONVERT_R16_IEEE)
1172 1.1.1.3 mrg && kind == 16
1173 1.1.1.3 mrg && (type == BT_REAL || type == BT_COMPLEX))
1174 1.1.1.3 mrg {
1175 1.1.1.3 mrg char *pd = dest;
1176 1.1.1.3 mrg for (size_t i = 0; i < nelems; i++)
1177 1.1.1.3 mrg {
1178 1.1.1.3 mrg GFC_REAL_16 r16;
1179 1.1.1.3 mrg GFC_REAL_17 r17;
1180 1.1.1.3 mrg memcpy (&r17, pd, 16);
1181 1.1.1.3 mrg r16 = r17;
1182 1.1.1.3 mrg memcpy (pd, &r16, 16);
1183 1.1.1.3 mrg pd += size;
1184 1.1.1.3 mrg }
1185 1.1.1.3 mrg }
1186 1.1.1.3 mrg else if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IBM)
1187 1.1.1.3 mrg && kind == 17
1188 1.1.1.3 mrg && (type == BT_REAL || type == BT_COMPLEX))
1189 1.1.1.3 mrg {
1190 1.1.1.3 mrg if (type == BT_COMPLEX && size == 32)
1191 1.1.1.3 mrg {
1192 1.1.1.3 mrg nelems *= 2;
1193 1.1.1.3 mrg size /= 2;
1194 1.1.1.3 mrg }
1195 1.1.1.3 mrg
1196 1.1.1.3 mrg char *pd = dest;
1197 1.1.1.3 mrg for (size_t i = 0; i < nelems; i++)
1198 1.1.1.3 mrg {
1199 1.1.1.3 mrg GFC_REAL_16 r16;
1200 1.1.1.3 mrg GFC_REAL_17 r17;
1201 1.1.1.3 mrg memcpy (&r16, pd, 16);
1202 1.1.1.3 mrg r17 = r16;
1203 1.1.1.3 mrg memcpy (pd, &r17, 16);
1204 1.1.1.3 mrg pd += size;
1205 1.1.1.3 mrg }
1206 1.1.1.3 mrg }
1207 1.1.1.3 mrg #endif /* HAVE_GFC_REAL_17. */
1208 1.1 mrg }
1209 1.1 mrg }
1210 1.1 mrg
1211 1.1 mrg
1212 1.1 mrg /* Master function for unformatted writes. NOTE: For kind=10 the size is 16
1213 1.1 mrg bytes on 64 bit machines. The unused bytes are not initialized and never
1214 1.1 mrg used, which can show an error with memory checking analyzers like
1215 1.1 mrg valgrind. We us BT_CLASS to denote a User Defined I/O call. */
1216 1.1 mrg
1217 1.1 mrg static void
1218 1.1 mrg unformatted_write (st_parameter_dt *dtp, bt type,
1219 1.1 mrg void *source, int kind, size_t size, size_t nelems)
1220 1.1 mrg {
1221 1.1.1.3 mrg unit_convert convert;
1222 1.1.1.3 mrg
1223 1.1 mrg if (type == BT_CLASS)
1224 1.1 mrg {
1225 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
1226 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
1227 1.1 mrg char *child_iomsg;
1228 1.1 mrg gfc_charlen_type child_iomsg_len;
1229 1.1 mrg int noiostat;
1230 1.1 mrg int *child_iostat = NULL;
1231 1.1 mrg
1232 1.1 mrg /* Set iostat, intent(out). */
1233 1.1 mrg noiostat = 0;
1234 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1235 1.1 mrg dtp->common.iostat : &noiostat;
1236 1.1 mrg
1237 1.1 mrg /* Set iomsg, intent(inout). */
1238 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
1239 1.1 mrg {
1240 1.1 mrg child_iomsg = dtp->common.iomsg;
1241 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
1242 1.1 mrg }
1243 1.1 mrg else
1244 1.1 mrg {
1245 1.1 mrg child_iomsg = tmp_iomsg;
1246 1.1 mrg child_iomsg_len = IOMSG_LEN;
1247 1.1 mrg }
1248 1.1 mrg
1249 1.1 mrg /* Call the user defined unformatted WRITE procedure. */
1250 1.1 mrg dtp->u.p.current_unit->child_dtio++;
1251 1.1 mrg dtp->u.p.ufdtio_ptr (source, &unit, child_iostat, child_iomsg,
1252 1.1 mrg child_iomsg_len);
1253 1.1 mrg dtp->u.p.current_unit->child_dtio--;
1254 1.1 mrg return;
1255 1.1 mrg }
1256 1.1 mrg
1257 1.1.1.3 mrg convert = dtp->u.p.current_unit->flags.convert;
1258 1.1.1.3 mrg if (likely (convert == GFC_CONVERT_NATIVE) || kind == 1
1259 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
1260 1.1.1.3 mrg || ((type == BT_REAL || type == BT_COMPLEX)
1261 1.1.1.3 mrg && ((kind == 16 && convert == GFC_CONVERT_R16_IBM)
1262 1.1.1.3 mrg || (kind == 17 && convert == GFC_CONVERT_R16_IEEE)))
1263 1.1.1.3 mrg #endif
1264 1.1.1.3 mrg )
1265 1.1 mrg {
1266 1.1 mrg size_t stride = type == BT_CHARACTER ?
1267 1.1 mrg size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1268 1.1 mrg
1269 1.1 mrg write_buf (dtp, source, stride * nelems);
1270 1.1 mrg }
1271 1.1 mrg else
1272 1.1 mrg {
1273 1.1 mrg #define BSWAP_BUFSZ 512
1274 1.1 mrg char buffer[BSWAP_BUFSZ];
1275 1.1 mrg char *p;
1276 1.1 mrg size_t nrem;
1277 1.1 mrg
1278 1.1 mrg p = source;
1279 1.1 mrg
1280 1.1 mrg /* Handle wide chracters. */
1281 1.1 mrg if (type == BT_CHARACTER && kind != 1)
1282 1.1 mrg {
1283 1.1 mrg nelems *= size;
1284 1.1 mrg size = kind;
1285 1.1 mrg }
1286 1.1 mrg
1287 1.1 mrg /* Break up complex into its constituent reals. */
1288 1.1 mrg if (type == BT_COMPLEX)
1289 1.1 mrg {
1290 1.1 mrg nelems *= 2;
1291 1.1 mrg size /= 2;
1292 1.1 mrg }
1293 1.1 mrg
1294 1.1.1.3 mrg #if !defined(HAVE_GFC_REAL_17) && defined(HAVE_GFC_REAL_16) \
1295 1.1.1.3 mrg && GFC_REAL_16_DIGITS == 106
1296 1.1.1.3 mrg /* IBM extended format is stored as a pair of IEEE754
1297 1.1.1.3 mrg double values, with the more significant value first
1298 1.1.1.3 mrg in both big and little endian. */
1299 1.1.1.3 mrg if (kind == 16 && (type == BT_REAL || type == BT_COMPLEX))
1300 1.1.1.3 mrg {
1301 1.1.1.3 mrg nelems *= 2;
1302 1.1.1.3 mrg size /= 2;
1303 1.1.1.3 mrg }
1304 1.1.1.3 mrg #endif
1305 1.1.1.3 mrg
1306 1.1 mrg /* By now, all complex variables have been split into their
1307 1.1 mrg constituent reals. */
1308 1.1 mrg
1309 1.1 mrg nrem = nelems;
1310 1.1 mrg do
1311 1.1 mrg {
1312 1.1 mrg size_t nc;
1313 1.1 mrg if (size * nrem > BSWAP_BUFSZ)
1314 1.1 mrg nc = BSWAP_BUFSZ / size;
1315 1.1 mrg else
1316 1.1 mrg nc = nrem;
1317 1.1 mrg
1318 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
1319 1.1.1.3 mrg if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IEEE)
1320 1.1.1.3 mrg && kind == 16
1321 1.1.1.3 mrg && (type == BT_REAL || type == BT_COMPLEX))
1322 1.1.1.3 mrg {
1323 1.1.1.3 mrg for (size_t i = 0; i < nc; i++)
1324 1.1.1.3 mrg {
1325 1.1.1.3 mrg GFC_REAL_16 r16;
1326 1.1.1.3 mrg GFC_REAL_17 r17;
1327 1.1.1.3 mrg memcpy (&r16, p, 16);
1328 1.1.1.3 mrg r17 = r16;
1329 1.1.1.3 mrg memcpy (&buffer[i * 16], &r17, 16);
1330 1.1.1.3 mrg p += 16;
1331 1.1.1.3 mrg }
1332 1.1.1.3 mrg if ((dtp->u.p.current_unit->flags.convert
1333 1.1.1.3 mrg & ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM))
1334 1.1.1.3 mrg == GFC_CONVERT_SWAP)
1335 1.1.1.3 mrg bswap_array (buffer, buffer, size, nc);
1336 1.1.1.3 mrg }
1337 1.1.1.3 mrg else if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IBM)
1338 1.1.1.3 mrg && kind == 17
1339 1.1.1.3 mrg && (type == BT_REAL || type == BT_COMPLEX))
1340 1.1.1.3 mrg {
1341 1.1.1.3 mrg for (size_t i = 0; i < nc; i++)
1342 1.1.1.3 mrg {
1343 1.1.1.3 mrg GFC_REAL_16 r16;
1344 1.1.1.3 mrg GFC_REAL_17 r17;
1345 1.1.1.3 mrg memcpy (&r17, p, 16);
1346 1.1.1.3 mrg r16 = r17;
1347 1.1.1.3 mrg memcpy (&buffer[i * 16], &r16, 16);
1348 1.1.1.3 mrg p += 16;
1349 1.1.1.3 mrg }
1350 1.1.1.3 mrg if ((dtp->u.p.current_unit->flags.convert
1351 1.1.1.3 mrg & ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM))
1352 1.1.1.3 mrg == GFC_CONVERT_SWAP)
1353 1.1.1.3 mrg bswap_array (buffer, buffer, size / 2, nc * 2);
1354 1.1.1.3 mrg }
1355 1.1.1.3 mrg else if (kind == 16 && (type == BT_REAL || type == BT_COMPLEX))
1356 1.1.1.3 mrg {
1357 1.1.1.3 mrg bswap_array (buffer, p, size / 2, nc * 2);
1358 1.1.1.3 mrg p += size * nc;
1359 1.1.1.3 mrg }
1360 1.1.1.3 mrg else
1361 1.1.1.3 mrg #endif
1362 1.1.1.3 mrg {
1363 1.1.1.3 mrg bswap_array (buffer, p, size, nc);
1364 1.1.1.3 mrg p += size * nc;
1365 1.1.1.3 mrg }
1366 1.1 mrg write_buf (dtp, buffer, size * nc);
1367 1.1 mrg nrem -= nc;
1368 1.1 mrg }
1369 1.1 mrg while (nrem > 0);
1370 1.1 mrg }
1371 1.1 mrg }
1372 1.1 mrg
1373 1.1 mrg
1374 1.1 mrg /* Return a pointer to the name of a type. */
1375 1.1 mrg
1376 1.1 mrg const char *
1377 1.1 mrg type_name (bt type)
1378 1.1 mrg {
1379 1.1 mrg const char *p;
1380 1.1 mrg
1381 1.1 mrg switch (type)
1382 1.1 mrg {
1383 1.1 mrg case BT_INTEGER:
1384 1.1 mrg p = "INTEGER";
1385 1.1 mrg break;
1386 1.1 mrg case BT_LOGICAL:
1387 1.1 mrg p = "LOGICAL";
1388 1.1 mrg break;
1389 1.1 mrg case BT_CHARACTER:
1390 1.1 mrg p = "CHARACTER";
1391 1.1 mrg break;
1392 1.1 mrg case BT_REAL:
1393 1.1 mrg p = "REAL";
1394 1.1 mrg break;
1395 1.1 mrg case BT_COMPLEX:
1396 1.1 mrg p = "COMPLEX";
1397 1.1 mrg break;
1398 1.1 mrg case BT_CLASS:
1399 1.1 mrg p = "CLASS or DERIVED";
1400 1.1 mrg break;
1401 1.1 mrg default:
1402 1.1 mrg internal_error (NULL, "type_name(): Bad type");
1403 1.1 mrg }
1404 1.1 mrg
1405 1.1 mrg return p;
1406 1.1 mrg }
1407 1.1 mrg
1408 1.1 mrg
1409 1.1 mrg /* Write a constant string to the output.
1410 1.1 mrg This is complicated because the string can have doubled delimiters
1411 1.1 mrg in it. The length in the format node is the true length. */
1412 1.1 mrg
1413 1.1 mrg static void
1414 1.1 mrg write_constant_string (st_parameter_dt *dtp, const fnode *f)
1415 1.1 mrg {
1416 1.1 mrg char c, delimiter, *p, *q;
1417 1.1 mrg int length;
1418 1.1 mrg
1419 1.1 mrg length = f->u.string.length;
1420 1.1 mrg if (length == 0)
1421 1.1 mrg return;
1422 1.1 mrg
1423 1.1 mrg p = write_block (dtp, length);
1424 1.1 mrg if (p == NULL)
1425 1.1 mrg return;
1426 1.1 mrg
1427 1.1 mrg q = f->u.string.p;
1428 1.1 mrg delimiter = q[-1];
1429 1.1 mrg
1430 1.1 mrg for (; length > 0; length--)
1431 1.1 mrg {
1432 1.1 mrg c = *p++ = *q++;
1433 1.1 mrg if (c == delimiter && c != 'H' && c != 'h')
1434 1.1 mrg q++; /* Skip the doubled delimiter. */
1435 1.1 mrg }
1436 1.1 mrg }
1437 1.1 mrg
1438 1.1 mrg
1439 1.1 mrg /* Given actual and expected types in a formatted data transfer, make
1440 1.1 mrg sure they agree. If not, an error message is generated. Returns
1441 1.1 mrg nonzero if something went wrong. */
1442 1.1 mrg
1443 1.1 mrg static int
1444 1.1 mrg require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
1445 1.1 mrg {
1446 1.1 mrg #define BUFLEN 100
1447 1.1 mrg char buffer[BUFLEN];
1448 1.1 mrg
1449 1.1 mrg if (actual == expected)
1450 1.1 mrg return 0;
1451 1.1 mrg
1452 1.1 mrg /* Adjust item_count before emitting error message. */
1453 1.1 mrg snprintf (buffer, BUFLEN,
1454 1.1 mrg "Expected %s for item %d in formatted transfer, got %s",
1455 1.1 mrg type_name (expected), dtp->u.p.item_count - 1, type_name (actual));
1456 1.1 mrg
1457 1.1 mrg format_error (dtp, f, buffer);
1458 1.1 mrg return 1;
1459 1.1 mrg }
1460 1.1 mrg
1461 1.1 mrg
1462 1.1 mrg /* Check that the dtio procedure required for formatted IO is present. */
1463 1.1 mrg
1464 1.1 mrg static int
1465 1.1 mrg check_dtio_proc (st_parameter_dt *dtp, const fnode *f)
1466 1.1 mrg {
1467 1.1 mrg char buffer[BUFLEN];
1468 1.1 mrg
1469 1.1 mrg if (dtp->u.p.fdtio_ptr != NULL)
1470 1.1 mrg return 0;
1471 1.1 mrg
1472 1.1 mrg snprintf (buffer, BUFLEN,
1473 1.1 mrg "Missing DTIO procedure or intrinsic type passed for item %d "
1474 1.1 mrg "in formatted transfer",
1475 1.1 mrg dtp->u.p.item_count - 1);
1476 1.1 mrg
1477 1.1 mrg format_error (dtp, f, buffer);
1478 1.1 mrg return 1;
1479 1.1 mrg }
1480 1.1 mrg
1481 1.1 mrg
1482 1.1 mrg static int
1483 1.1 mrg require_numeric_type (st_parameter_dt *dtp, bt actual, const fnode *f)
1484 1.1 mrg {
1485 1.1 mrg #define BUFLEN 100
1486 1.1 mrg char buffer[BUFLEN];
1487 1.1 mrg
1488 1.1 mrg if (actual == BT_INTEGER || actual == BT_REAL || actual == BT_COMPLEX)
1489 1.1 mrg return 0;
1490 1.1 mrg
1491 1.1 mrg /* Adjust item_count before emitting error message. */
1492 1.1 mrg snprintf (buffer, BUFLEN,
1493 1.1 mrg "Expected numeric type for item %d in formatted transfer, got %s",
1494 1.1 mrg dtp->u.p.item_count - 1, type_name (actual));
1495 1.1 mrg
1496 1.1 mrg format_error (dtp, f, buffer);
1497 1.1 mrg return 1;
1498 1.1 mrg }
1499 1.1 mrg
1500 1.1 mrg static char *
1501 1.1 mrg get_dt_format (char *p, gfc_charlen_type *length)
1502 1.1 mrg {
1503 1.1 mrg char delim = p[-1]; /* The delimiter is always the first character back. */
1504 1.1 mrg char c, *q, *res;
1505 1.1 mrg gfc_charlen_type len = *length; /* This length already correct, less 'DT'. */
1506 1.1 mrg
1507 1.1 mrg res = q = xmalloc (len + 2);
1508 1.1 mrg
1509 1.1 mrg /* Set the beginning of the string to 'DT', length adjusted below. */
1510 1.1 mrg *q++ = 'D';
1511 1.1 mrg *q++ = 'T';
1512 1.1 mrg
1513 1.1 mrg /* The string may contain doubled quotes so scan and skip as needed. */
1514 1.1 mrg for (; len > 0; len--)
1515 1.1 mrg {
1516 1.1 mrg c = *q++ = *p++;
1517 1.1 mrg if (c == delim)
1518 1.1 mrg p++; /* Skip the doubled delimiter. */
1519 1.1 mrg }
1520 1.1 mrg
1521 1.1 mrg /* Adjust the string length by two now that we are done. */
1522 1.1 mrg *length += 2;
1523 1.1 mrg
1524 1.1 mrg return res;
1525 1.1 mrg }
1526 1.1 mrg
1527 1.1 mrg
1528 1.1 mrg /* This function is in the main loop for a formatted data transfer
1529 1.1 mrg statement. It would be natural to implement this as a coroutine
1530 1.1 mrg with the user program, but C makes that awkward. We loop,
1531 1.1 mrg processing format elements. When we actually have to transfer
1532 1.1 mrg data instead of just setting flags, we return control to the user
1533 1.1 mrg program which calls a function that supplies the address and type
1534 1.1 mrg of the next element, then comes back here to process it. */
1535 1.1 mrg
1536 1.1 mrg static void
1537 1.1 mrg formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind,
1538 1.1 mrg size_t size)
1539 1.1 mrg {
1540 1.1 mrg int pos, bytes_used;
1541 1.1 mrg const fnode *f;
1542 1.1 mrg format_token t;
1543 1.1 mrg int n;
1544 1.1 mrg int consume_data_flag;
1545 1.1 mrg
1546 1.1 mrg /* Change a complex data item into a pair of reals. */
1547 1.1 mrg
1548 1.1 mrg n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
1549 1.1 mrg if (type == BT_COMPLEX)
1550 1.1 mrg {
1551 1.1 mrg type = BT_REAL;
1552 1.1 mrg size /= 2;
1553 1.1 mrg }
1554 1.1 mrg
1555 1.1 mrg /* If there's an EOR condition, we simulate finalizing the transfer
1556 1.1 mrg by doing nothing. */
1557 1.1 mrg if (dtp->u.p.eor_condition)
1558 1.1 mrg return;
1559 1.1 mrg
1560 1.1 mrg /* Set this flag so that commas in reads cause the read to complete before
1561 1.1 mrg the entire field has been read. The next read field will start right after
1562 1.1 mrg the comma in the stream. (Set to 0 for character reads). */
1563 1.1 mrg dtp->u.p.sf_read_comma =
1564 1.1 mrg dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
1565 1.1 mrg
1566 1.1 mrg for (;;)
1567 1.1 mrg {
1568 1.1 mrg /* If reversion has occurred and there is another real data item,
1569 1.1 mrg then we have to move to the next record. */
1570 1.1 mrg if (dtp->u.p.reversion_flag && n > 0)
1571 1.1 mrg {
1572 1.1 mrg dtp->u.p.reversion_flag = 0;
1573 1.1 mrg next_record (dtp, 0);
1574 1.1 mrg }
1575 1.1 mrg
1576 1.1 mrg consume_data_flag = 1;
1577 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1578 1.1 mrg break;
1579 1.1 mrg
1580 1.1 mrg f = next_format (dtp);
1581 1.1 mrg if (f == NULL)
1582 1.1 mrg {
1583 1.1 mrg /* No data descriptors left. */
1584 1.1 mrg if (unlikely (n > 0))
1585 1.1 mrg generate_error (&dtp->common, LIBERROR_FORMAT,
1586 1.1 mrg "Insufficient data descriptors in format after reversion");
1587 1.1 mrg return;
1588 1.1 mrg }
1589 1.1 mrg
1590 1.1 mrg t = f->format;
1591 1.1 mrg
1592 1.1 mrg bytes_used = (int)(dtp->u.p.current_unit->recl
1593 1.1 mrg - dtp->u.p.current_unit->bytes_left);
1594 1.1 mrg
1595 1.1 mrg if (is_stream_io(dtp))
1596 1.1 mrg bytes_used = 0;
1597 1.1 mrg
1598 1.1 mrg switch (t)
1599 1.1 mrg {
1600 1.1 mrg case FMT_I:
1601 1.1 mrg if (n == 0)
1602 1.1 mrg goto need_read_data;
1603 1.1 mrg if (require_type (dtp, BT_INTEGER, type, f))
1604 1.1 mrg return;
1605 1.1 mrg read_decimal (dtp, f, p, kind);
1606 1.1 mrg break;
1607 1.1 mrg
1608 1.1 mrg case FMT_B:
1609 1.1 mrg if (n == 0)
1610 1.1 mrg goto need_read_data;
1611 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1612 1.1 mrg && require_numeric_type (dtp, type, f))
1613 1.1 mrg return;
1614 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1615 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1616 1.1 mrg return;
1617 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
1618 1.1.1.3 mrg if (type == BT_REAL && kind == 17)
1619 1.1.1.3 mrg kind = 16;
1620 1.1.1.3 mrg #endif
1621 1.1 mrg read_radix (dtp, f, p, kind, 2);
1622 1.1 mrg break;
1623 1.1 mrg
1624 1.1 mrg case FMT_O:
1625 1.1 mrg if (n == 0)
1626 1.1 mrg goto need_read_data;
1627 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1628 1.1 mrg && require_numeric_type (dtp, type, f))
1629 1.1 mrg return;
1630 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1631 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1632 1.1 mrg return;
1633 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
1634 1.1.1.3 mrg if (type == BT_REAL && kind == 17)
1635 1.1.1.3 mrg kind = 16;
1636 1.1.1.3 mrg #endif
1637 1.1 mrg read_radix (dtp, f, p, kind, 8);
1638 1.1 mrg break;
1639 1.1 mrg
1640 1.1 mrg case FMT_Z:
1641 1.1 mrg if (n == 0)
1642 1.1 mrg goto need_read_data;
1643 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1644 1.1 mrg && require_numeric_type (dtp, type, f))
1645 1.1 mrg return;
1646 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1647 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1648 1.1 mrg return;
1649 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
1650 1.1.1.3 mrg if (type == BT_REAL && kind == 17)
1651 1.1.1.3 mrg kind = 16;
1652 1.1.1.3 mrg #endif
1653 1.1 mrg read_radix (dtp, f, p, kind, 16);
1654 1.1 mrg break;
1655 1.1 mrg
1656 1.1 mrg case FMT_A:
1657 1.1 mrg if (n == 0)
1658 1.1 mrg goto need_read_data;
1659 1.1 mrg
1660 1.1 mrg /* It is possible to have FMT_A with something not BT_CHARACTER such
1661 1.1 mrg as when writing out hollerith strings, so check both type
1662 1.1 mrg and kind before calling wide character routines. */
1663 1.1 mrg if (type == BT_CHARACTER && kind == 4)
1664 1.1 mrg read_a_char4 (dtp, f, p, size);
1665 1.1 mrg else
1666 1.1 mrg read_a (dtp, f, p, size);
1667 1.1 mrg break;
1668 1.1 mrg
1669 1.1 mrg case FMT_L:
1670 1.1 mrg if (n == 0)
1671 1.1 mrg goto need_read_data;
1672 1.1 mrg read_l (dtp, f, p, kind);
1673 1.1 mrg break;
1674 1.1 mrg
1675 1.1 mrg case FMT_D:
1676 1.1 mrg if (n == 0)
1677 1.1 mrg goto need_read_data;
1678 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1679 1.1 mrg return;
1680 1.1 mrg read_f (dtp, f, p, kind);
1681 1.1 mrg break;
1682 1.1 mrg
1683 1.1 mrg case FMT_DT:
1684 1.1 mrg if (n == 0)
1685 1.1 mrg goto need_read_data;
1686 1.1 mrg
1687 1.1 mrg if (check_dtio_proc (dtp, f))
1688 1.1 mrg return;
1689 1.1 mrg if (require_type (dtp, BT_CLASS, type, f))
1690 1.1 mrg return;
1691 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
1692 1.1 mrg char dt[] = "DT";
1693 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
1694 1.1 mrg char *child_iomsg;
1695 1.1 mrg gfc_charlen_type child_iomsg_len;
1696 1.1 mrg int noiostat;
1697 1.1 mrg int *child_iostat = NULL;
1698 1.1 mrg char *iotype;
1699 1.1 mrg gfc_charlen_type iotype_len = f->u.udf.string_len;
1700 1.1 mrg
1701 1.1 mrg /* Build the iotype string. */
1702 1.1 mrg if (iotype_len == 0)
1703 1.1 mrg {
1704 1.1 mrg iotype_len = 2;
1705 1.1 mrg iotype = dt;
1706 1.1 mrg }
1707 1.1 mrg else
1708 1.1 mrg iotype = get_dt_format (f->u.udf.string, &iotype_len);
1709 1.1 mrg
1710 1.1 mrg /* Set iostat, intent(out). */
1711 1.1 mrg noiostat = 0;
1712 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1713 1.1 mrg dtp->common.iostat : &noiostat;
1714 1.1 mrg
1715 1.1 mrg /* Set iomsg, intent(inout). */
1716 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
1717 1.1 mrg {
1718 1.1 mrg child_iomsg = dtp->common.iomsg;
1719 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
1720 1.1 mrg }
1721 1.1 mrg else
1722 1.1 mrg {
1723 1.1 mrg child_iomsg = tmp_iomsg;
1724 1.1 mrg child_iomsg_len = IOMSG_LEN;
1725 1.1 mrg }
1726 1.1 mrg
1727 1.1 mrg /* Call the user defined formatted READ procedure. */
1728 1.1 mrg dtp->u.p.current_unit->child_dtio++;
1729 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
1730 1.1 mrg dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
1731 1.1 mrg child_iostat, child_iomsg,
1732 1.1 mrg iotype_len, child_iomsg_len);
1733 1.1 mrg dtp->u.p.current_unit->child_dtio--;
1734 1.1 mrg
1735 1.1 mrg if (f->u.udf.string_len != 0)
1736 1.1 mrg free (iotype);
1737 1.1 mrg /* Note: vlist is freed in free_format_data. */
1738 1.1 mrg break;
1739 1.1 mrg
1740 1.1 mrg case FMT_E:
1741 1.1 mrg if (n == 0)
1742 1.1 mrg goto need_read_data;
1743 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1744 1.1 mrg return;
1745 1.1 mrg read_f (dtp, f, p, kind);
1746 1.1 mrg break;
1747 1.1 mrg
1748 1.1 mrg case FMT_EN:
1749 1.1 mrg if (n == 0)
1750 1.1 mrg goto need_read_data;
1751 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1752 1.1 mrg return;
1753 1.1 mrg read_f (dtp, f, p, kind);
1754 1.1 mrg break;
1755 1.1 mrg
1756 1.1 mrg case FMT_ES:
1757 1.1 mrg if (n == 0)
1758 1.1 mrg goto need_read_data;
1759 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1760 1.1 mrg return;
1761 1.1 mrg read_f (dtp, f, p, kind);
1762 1.1 mrg break;
1763 1.1 mrg
1764 1.1 mrg case FMT_F:
1765 1.1 mrg if (n == 0)
1766 1.1 mrg goto need_read_data;
1767 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1768 1.1 mrg return;
1769 1.1 mrg read_f (dtp, f, p, kind);
1770 1.1 mrg break;
1771 1.1 mrg
1772 1.1 mrg case FMT_G:
1773 1.1 mrg if (n == 0)
1774 1.1 mrg goto need_read_data;
1775 1.1 mrg switch (type)
1776 1.1 mrg {
1777 1.1 mrg case BT_INTEGER:
1778 1.1 mrg read_decimal (dtp, f, p, kind);
1779 1.1 mrg break;
1780 1.1 mrg case BT_LOGICAL:
1781 1.1 mrg read_l (dtp, f, p, kind);
1782 1.1 mrg break;
1783 1.1 mrg case BT_CHARACTER:
1784 1.1 mrg if (kind == 4)
1785 1.1 mrg read_a_char4 (dtp, f, p, size);
1786 1.1 mrg else
1787 1.1 mrg read_a (dtp, f, p, size);
1788 1.1 mrg break;
1789 1.1 mrg case BT_REAL:
1790 1.1 mrg read_f (dtp, f, p, kind);
1791 1.1 mrg break;
1792 1.1 mrg default:
1793 1.1 mrg internal_error (&dtp->common,
1794 1.1 mrg "formatted_transfer (): Bad type");
1795 1.1 mrg }
1796 1.1 mrg break;
1797 1.1 mrg
1798 1.1 mrg case FMT_STRING:
1799 1.1 mrg consume_data_flag = 0;
1800 1.1 mrg format_error (dtp, f, "Constant string in input format");
1801 1.1 mrg return;
1802 1.1 mrg
1803 1.1 mrg /* Format codes that don't transfer data. */
1804 1.1 mrg case FMT_X:
1805 1.1 mrg case FMT_TR:
1806 1.1 mrg consume_data_flag = 0;
1807 1.1 mrg dtp->u.p.skips += f->u.n;
1808 1.1 mrg pos = bytes_used + dtp->u.p.skips - 1;
1809 1.1 mrg dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
1810 1.1 mrg read_x (dtp, f->u.n);
1811 1.1 mrg break;
1812 1.1 mrg
1813 1.1 mrg case FMT_TL:
1814 1.1 mrg case FMT_T:
1815 1.1 mrg consume_data_flag = 0;
1816 1.1 mrg
1817 1.1 mrg if (f->format == FMT_TL)
1818 1.1 mrg {
1819 1.1 mrg /* Handle the special case when no bytes have been used yet.
1820 1.1 mrg Cannot go below zero. */
1821 1.1 mrg if (bytes_used == 0)
1822 1.1 mrg {
1823 1.1 mrg dtp->u.p.pending_spaces -= f->u.n;
1824 1.1 mrg dtp->u.p.skips -= f->u.n;
1825 1.1 mrg dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
1826 1.1 mrg }
1827 1.1 mrg
1828 1.1 mrg pos = bytes_used - f->u.n;
1829 1.1 mrg }
1830 1.1 mrg else /* FMT_T */
1831 1.1 mrg pos = f->u.n - 1;
1832 1.1 mrg
1833 1.1 mrg /* Standard 10.6.1.1: excessive left tabbing is reset to the
1834 1.1 mrg left tab limit. We do not check if the position has gone
1835 1.1 mrg beyond the end of record because a subsequent tab could
1836 1.1 mrg bring us back again. */
1837 1.1 mrg pos = pos < 0 ? 0 : pos;
1838 1.1 mrg
1839 1.1 mrg dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
1840 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
1841 1.1 mrg + pos - dtp->u.p.max_pos;
1842 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
1843 1.1 mrg ? 0 : dtp->u.p.pending_spaces;
1844 1.1 mrg if (dtp->u.p.skips == 0)
1845 1.1 mrg break;
1846 1.1 mrg
1847 1.1 mrg /* Adjust everything for end-of-record condition */
1848 1.1 mrg if (dtp->u.p.sf_seen_eor && !is_internal_unit (dtp))
1849 1.1 mrg {
1850 1.1 mrg dtp->u.p.current_unit->bytes_left -= dtp->u.p.sf_seen_eor;
1851 1.1 mrg dtp->u.p.skips -= dtp->u.p.sf_seen_eor;
1852 1.1 mrg bytes_used = pos;
1853 1.1 mrg if (dtp->u.p.pending_spaces == 0)
1854 1.1 mrg dtp->u.p.sf_seen_eor = 0;
1855 1.1 mrg }
1856 1.1 mrg if (dtp->u.p.skips < 0)
1857 1.1 mrg {
1858 1.1 mrg if (is_internal_unit (dtp))
1859 1.1 mrg sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
1860 1.1 mrg else
1861 1.1 mrg fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
1862 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
1863 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1864 1.1 mrg }
1865 1.1 mrg else
1866 1.1 mrg read_x (dtp, dtp->u.p.skips);
1867 1.1 mrg break;
1868 1.1 mrg
1869 1.1 mrg case FMT_S:
1870 1.1 mrg consume_data_flag = 0;
1871 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PROCDEFINED;
1872 1.1 mrg break;
1873 1.1 mrg
1874 1.1 mrg case FMT_SS:
1875 1.1 mrg consume_data_flag = 0;
1876 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_SUPPRESS;
1877 1.1 mrg break;
1878 1.1 mrg
1879 1.1 mrg case FMT_SP:
1880 1.1 mrg consume_data_flag = 0;
1881 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PLUS;
1882 1.1 mrg break;
1883 1.1 mrg
1884 1.1 mrg case FMT_BN:
1885 1.1 mrg consume_data_flag = 0 ;
1886 1.1 mrg dtp->u.p.blank_status = BLANK_NULL;
1887 1.1 mrg break;
1888 1.1 mrg
1889 1.1 mrg case FMT_BZ:
1890 1.1 mrg consume_data_flag = 0;
1891 1.1 mrg dtp->u.p.blank_status = BLANK_ZERO;
1892 1.1 mrg break;
1893 1.1 mrg
1894 1.1 mrg case FMT_DC:
1895 1.1 mrg consume_data_flag = 0;
1896 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
1897 1.1 mrg break;
1898 1.1 mrg
1899 1.1 mrg case FMT_DP:
1900 1.1 mrg consume_data_flag = 0;
1901 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
1902 1.1 mrg break;
1903 1.1 mrg
1904 1.1 mrg case FMT_RC:
1905 1.1 mrg consume_data_flag = 0;
1906 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
1907 1.1 mrg break;
1908 1.1 mrg
1909 1.1 mrg case FMT_RD:
1910 1.1 mrg consume_data_flag = 0;
1911 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_DOWN;
1912 1.1 mrg break;
1913 1.1 mrg
1914 1.1 mrg case FMT_RN:
1915 1.1 mrg consume_data_flag = 0;
1916 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_NEAREST;
1917 1.1 mrg break;
1918 1.1 mrg
1919 1.1 mrg case FMT_RP:
1920 1.1 mrg consume_data_flag = 0;
1921 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
1922 1.1 mrg break;
1923 1.1 mrg
1924 1.1 mrg case FMT_RU:
1925 1.1 mrg consume_data_flag = 0;
1926 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_UP;
1927 1.1 mrg break;
1928 1.1 mrg
1929 1.1 mrg case FMT_RZ:
1930 1.1 mrg consume_data_flag = 0;
1931 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_ZERO;
1932 1.1 mrg break;
1933 1.1 mrg
1934 1.1 mrg case FMT_P:
1935 1.1 mrg consume_data_flag = 0;
1936 1.1 mrg dtp->u.p.scale_factor = f->u.k;
1937 1.1 mrg break;
1938 1.1 mrg
1939 1.1 mrg case FMT_DOLLAR:
1940 1.1 mrg consume_data_flag = 0;
1941 1.1 mrg dtp->u.p.seen_dollar = 1;
1942 1.1 mrg break;
1943 1.1 mrg
1944 1.1 mrg case FMT_SLASH:
1945 1.1 mrg consume_data_flag = 0;
1946 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1947 1.1 mrg next_record (dtp, 0);
1948 1.1 mrg break;
1949 1.1 mrg
1950 1.1 mrg case FMT_COLON:
1951 1.1 mrg /* A colon descriptor causes us to exit this loop (in
1952 1.1 mrg particular preventing another / descriptor from being
1953 1.1 mrg processed) unless there is another data item to be
1954 1.1 mrg transferred. */
1955 1.1 mrg consume_data_flag = 0;
1956 1.1 mrg if (n == 0)
1957 1.1 mrg return;
1958 1.1 mrg break;
1959 1.1 mrg
1960 1.1 mrg default:
1961 1.1 mrg internal_error (&dtp->common, "Bad format node");
1962 1.1 mrg }
1963 1.1 mrg
1964 1.1 mrg /* Adjust the item count and data pointer. */
1965 1.1 mrg
1966 1.1 mrg if ((consume_data_flag > 0) && (n > 0))
1967 1.1 mrg {
1968 1.1 mrg n--;
1969 1.1 mrg p = ((char *) p) + size;
1970 1.1 mrg }
1971 1.1 mrg
1972 1.1 mrg dtp->u.p.skips = 0;
1973 1.1 mrg
1974 1.1 mrg pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
1975 1.1 mrg dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
1976 1.1 mrg }
1977 1.1 mrg
1978 1.1 mrg return;
1979 1.1 mrg
1980 1.1 mrg /* Come here when we need a data descriptor but don't have one. We
1981 1.1 mrg push the current format node back onto the input, then return and
1982 1.1 mrg let the user program call us back with the data. */
1983 1.1 mrg need_read_data:
1984 1.1 mrg unget_format (dtp, f);
1985 1.1 mrg }
1986 1.1 mrg
1987 1.1 mrg
1988 1.1 mrg static void
1989 1.1 mrg formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1990 1.1 mrg size_t size)
1991 1.1 mrg {
1992 1.1 mrg gfc_offset pos, bytes_used;
1993 1.1 mrg const fnode *f;
1994 1.1 mrg format_token t;
1995 1.1 mrg int n;
1996 1.1 mrg int consume_data_flag;
1997 1.1 mrg
1998 1.1 mrg /* Change a complex data item into a pair of reals. */
1999 1.1 mrg
2000 1.1 mrg n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
2001 1.1 mrg if (type == BT_COMPLEX)
2002 1.1 mrg {
2003 1.1 mrg type = BT_REAL;
2004 1.1 mrg size /= 2;
2005 1.1 mrg }
2006 1.1 mrg
2007 1.1 mrg /* If there's an EOR condition, we simulate finalizing the transfer
2008 1.1 mrg by doing nothing. */
2009 1.1 mrg if (dtp->u.p.eor_condition)
2010 1.1 mrg return;
2011 1.1 mrg
2012 1.1 mrg /* Set this flag so that commas in reads cause the read to complete before
2013 1.1 mrg the entire field has been read. The next read field will start right after
2014 1.1 mrg the comma in the stream. (Set to 0 for character reads). */
2015 1.1 mrg dtp->u.p.sf_read_comma =
2016 1.1 mrg dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
2017 1.1 mrg
2018 1.1 mrg for (;;)
2019 1.1 mrg {
2020 1.1 mrg /* If reversion has occurred and there is another real data item,
2021 1.1 mrg then we have to move to the next record. */
2022 1.1 mrg if (dtp->u.p.reversion_flag && n > 0)
2023 1.1 mrg {
2024 1.1 mrg dtp->u.p.reversion_flag = 0;
2025 1.1 mrg next_record (dtp, 0);
2026 1.1 mrg }
2027 1.1 mrg
2028 1.1 mrg consume_data_flag = 1;
2029 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2030 1.1 mrg break;
2031 1.1 mrg
2032 1.1 mrg f = next_format (dtp);
2033 1.1 mrg if (f == NULL)
2034 1.1 mrg {
2035 1.1 mrg /* No data descriptors left. */
2036 1.1 mrg if (unlikely (n > 0))
2037 1.1 mrg generate_error (&dtp->common, LIBERROR_FORMAT,
2038 1.1 mrg "Insufficient data descriptors in format after reversion");
2039 1.1 mrg return;
2040 1.1 mrg }
2041 1.1 mrg
2042 1.1 mrg /* Now discharge T, TR and X movements to the right. This is delayed
2043 1.1 mrg until a data producing format to suppress trailing spaces. */
2044 1.1 mrg
2045 1.1 mrg t = f->format;
2046 1.1 mrg if (dtp->u.p.mode == WRITING && dtp->u.p.skips != 0
2047 1.1 mrg && ((n>0 && ( t == FMT_I || t == FMT_B || t == FMT_O
2048 1.1 mrg || t == FMT_Z || t == FMT_F || t == FMT_E
2049 1.1 mrg || t == FMT_EN || t == FMT_ES || t == FMT_G
2050 1.1 mrg || t == FMT_L || t == FMT_A || t == FMT_D
2051 1.1 mrg || t == FMT_DT))
2052 1.1 mrg || t == FMT_STRING))
2053 1.1 mrg {
2054 1.1 mrg if (dtp->u.p.skips > 0)
2055 1.1 mrg {
2056 1.1 mrg gfc_offset tmp;
2057 1.1 mrg write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
2058 1.1 mrg tmp = dtp->u.p.current_unit->recl
2059 1.1 mrg - dtp->u.p.current_unit->bytes_left;
2060 1.1 mrg dtp->u.p.max_pos =
2061 1.1 mrg dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
2062 1.1 mrg dtp->u.p.skips = 0;
2063 1.1 mrg }
2064 1.1 mrg if (dtp->u.p.skips < 0)
2065 1.1 mrg {
2066 1.1 mrg if (is_internal_unit (dtp))
2067 1.1 mrg sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
2068 1.1 mrg else
2069 1.1 mrg fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
2070 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
2071 1.1 mrg }
2072 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2073 1.1 mrg }
2074 1.1 mrg
2075 1.1 mrg bytes_used = dtp->u.p.current_unit->recl
2076 1.1 mrg - dtp->u.p.current_unit->bytes_left;
2077 1.1 mrg
2078 1.1 mrg if (is_stream_io(dtp))
2079 1.1 mrg bytes_used = 0;
2080 1.1 mrg
2081 1.1 mrg switch (t)
2082 1.1 mrg {
2083 1.1 mrg case FMT_I:
2084 1.1 mrg if (n == 0)
2085 1.1 mrg goto need_data;
2086 1.1 mrg if (require_type (dtp, BT_INTEGER, type, f))
2087 1.1 mrg return;
2088 1.1 mrg write_i (dtp, f, p, kind);
2089 1.1 mrg break;
2090 1.1 mrg
2091 1.1 mrg case FMT_B:
2092 1.1 mrg if (n == 0)
2093 1.1 mrg goto need_data;
2094 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
2095 1.1 mrg && require_numeric_type (dtp, type, f))
2096 1.1 mrg return;
2097 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
2098 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
2099 1.1 mrg return;
2100 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
2101 1.1.1.3 mrg if (type == BT_REAL && kind == 17)
2102 1.1.1.3 mrg kind = 16;
2103 1.1.1.3 mrg #endif
2104 1.1 mrg write_b (dtp, f, p, kind);
2105 1.1 mrg break;
2106 1.1 mrg
2107 1.1 mrg case FMT_O:
2108 1.1 mrg if (n == 0)
2109 1.1 mrg goto need_data;
2110 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
2111 1.1 mrg && require_numeric_type (dtp, type, f))
2112 1.1 mrg return;
2113 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
2114 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
2115 1.1 mrg return;
2116 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
2117 1.1.1.3 mrg if (type == BT_REAL && kind == 17)
2118 1.1.1.3 mrg kind = 16;
2119 1.1.1.3 mrg #endif
2120 1.1 mrg write_o (dtp, f, p, kind);
2121 1.1 mrg break;
2122 1.1 mrg
2123 1.1 mrg case FMT_Z:
2124 1.1 mrg if (n == 0)
2125 1.1 mrg goto need_data;
2126 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
2127 1.1 mrg && require_numeric_type (dtp, type, f))
2128 1.1 mrg return;
2129 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
2130 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
2131 1.1 mrg return;
2132 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
2133 1.1.1.3 mrg if (type == BT_REAL && kind == 17)
2134 1.1.1.3 mrg kind = 16;
2135 1.1.1.3 mrg #endif
2136 1.1 mrg write_z (dtp, f, p, kind);
2137 1.1 mrg break;
2138 1.1 mrg
2139 1.1 mrg case FMT_A:
2140 1.1 mrg if (n == 0)
2141 1.1 mrg goto need_data;
2142 1.1 mrg
2143 1.1 mrg /* It is possible to have FMT_A with something not BT_CHARACTER such
2144 1.1 mrg as when writing out hollerith strings, so check both type
2145 1.1 mrg and kind before calling wide character routines. */
2146 1.1 mrg if (type == BT_CHARACTER && kind == 4)
2147 1.1 mrg write_a_char4 (dtp, f, p, size);
2148 1.1 mrg else
2149 1.1 mrg write_a (dtp, f, p, size);
2150 1.1 mrg break;
2151 1.1 mrg
2152 1.1 mrg case FMT_L:
2153 1.1 mrg if (n == 0)
2154 1.1 mrg goto need_data;
2155 1.1 mrg write_l (dtp, f, p, kind);
2156 1.1 mrg break;
2157 1.1 mrg
2158 1.1 mrg case FMT_D:
2159 1.1 mrg if (n == 0)
2160 1.1 mrg goto need_data;
2161 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2162 1.1 mrg return;
2163 1.1.1.2 mrg if (f->u.real.w == 0)
2164 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2165 1.1.1.2 mrg else
2166 1.1.1.2 mrg write_d (dtp, f, p, kind);
2167 1.1 mrg break;
2168 1.1 mrg
2169 1.1 mrg case FMT_DT:
2170 1.1 mrg if (n == 0)
2171 1.1 mrg goto need_data;
2172 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
2173 1.1 mrg char dt[] = "DT";
2174 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
2175 1.1 mrg char *child_iomsg;
2176 1.1 mrg gfc_charlen_type child_iomsg_len;
2177 1.1 mrg int noiostat;
2178 1.1 mrg int *child_iostat = NULL;
2179 1.1 mrg char *iotype;
2180 1.1 mrg gfc_charlen_type iotype_len = f->u.udf.string_len;
2181 1.1 mrg
2182 1.1 mrg /* Build the iotype string. */
2183 1.1 mrg if (iotype_len == 0)
2184 1.1 mrg {
2185 1.1 mrg iotype_len = 2;
2186 1.1 mrg iotype = dt;
2187 1.1 mrg }
2188 1.1 mrg else
2189 1.1 mrg iotype = get_dt_format (f->u.udf.string, &iotype_len);
2190 1.1 mrg
2191 1.1 mrg /* Set iostat, intent(out). */
2192 1.1 mrg noiostat = 0;
2193 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
2194 1.1 mrg dtp->common.iostat : &noiostat;
2195 1.1 mrg
2196 1.1 mrg /* Set iomsg, intent(inout). */
2197 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
2198 1.1 mrg {
2199 1.1 mrg child_iomsg = dtp->common.iomsg;
2200 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
2201 1.1 mrg }
2202 1.1 mrg else
2203 1.1 mrg {
2204 1.1 mrg child_iomsg = tmp_iomsg;
2205 1.1 mrg child_iomsg_len = IOMSG_LEN;
2206 1.1 mrg }
2207 1.1 mrg
2208 1.1 mrg if (check_dtio_proc (dtp, f))
2209 1.1 mrg return;
2210 1.1 mrg
2211 1.1 mrg /* Call the user defined formatted WRITE procedure. */
2212 1.1 mrg dtp->u.p.current_unit->child_dtio++;
2213 1.1 mrg
2214 1.1 mrg dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
2215 1.1 mrg child_iostat, child_iomsg,
2216 1.1 mrg iotype_len, child_iomsg_len);
2217 1.1 mrg dtp->u.p.current_unit->child_dtio--;
2218 1.1 mrg
2219 1.1 mrg if (f->u.udf.string_len != 0)
2220 1.1 mrg free (iotype);
2221 1.1 mrg /* Note: vlist is freed in free_format_data. */
2222 1.1 mrg break;
2223 1.1 mrg
2224 1.1 mrg case FMT_E:
2225 1.1 mrg if (n == 0)
2226 1.1 mrg goto need_data;
2227 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2228 1.1 mrg return;
2229 1.1.1.2 mrg if (f->u.real.w == 0)
2230 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2231 1.1.1.2 mrg else
2232 1.1.1.2 mrg write_e (dtp, f, p, kind);
2233 1.1 mrg break;
2234 1.1 mrg
2235 1.1 mrg case FMT_EN:
2236 1.1 mrg if (n == 0)
2237 1.1 mrg goto need_data;
2238 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2239 1.1 mrg return;
2240 1.1.1.2 mrg if (f->u.real.w == 0)
2241 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2242 1.1.1.2 mrg else
2243 1.1.1.2 mrg write_en (dtp, f, p, kind);
2244 1.1 mrg break;
2245 1.1 mrg
2246 1.1 mrg case FMT_ES:
2247 1.1 mrg if (n == 0)
2248 1.1 mrg goto need_data;
2249 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2250 1.1 mrg return;
2251 1.1.1.2 mrg if (f->u.real.w == 0)
2252 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2253 1.1.1.2 mrg else
2254 1.1.1.2 mrg write_es (dtp, f, p, kind);
2255 1.1 mrg break;
2256 1.1 mrg
2257 1.1 mrg case FMT_F:
2258 1.1 mrg if (n == 0)
2259 1.1 mrg goto need_data;
2260 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2261 1.1 mrg return;
2262 1.1 mrg write_f (dtp, f, p, kind);
2263 1.1 mrg break;
2264 1.1 mrg
2265 1.1 mrg case FMT_G:
2266 1.1 mrg if (n == 0)
2267 1.1 mrg goto need_data;
2268 1.1 mrg switch (type)
2269 1.1 mrg {
2270 1.1 mrg case BT_INTEGER:
2271 1.1 mrg write_i (dtp, f, p, kind);
2272 1.1 mrg break;
2273 1.1 mrg case BT_LOGICAL:
2274 1.1 mrg write_l (dtp, f, p, kind);
2275 1.1 mrg break;
2276 1.1 mrg case BT_CHARACTER:
2277 1.1 mrg if (kind == 4)
2278 1.1 mrg write_a_char4 (dtp, f, p, size);
2279 1.1 mrg else
2280 1.1 mrg write_a (dtp, f, p, size);
2281 1.1 mrg break;
2282 1.1 mrg case BT_REAL:
2283 1.1 mrg if (f->u.real.w == 0)
2284 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2285 1.1 mrg else
2286 1.1 mrg write_d (dtp, f, p, kind);
2287 1.1 mrg break;
2288 1.1 mrg default:
2289 1.1 mrg internal_error (&dtp->common,
2290 1.1 mrg "formatted_transfer (): Bad type");
2291 1.1 mrg }
2292 1.1 mrg break;
2293 1.1 mrg
2294 1.1 mrg case FMT_STRING:
2295 1.1 mrg consume_data_flag = 0;
2296 1.1 mrg write_constant_string (dtp, f);
2297 1.1 mrg break;
2298 1.1 mrg
2299 1.1 mrg /* Format codes that don't transfer data. */
2300 1.1 mrg case FMT_X:
2301 1.1 mrg case FMT_TR:
2302 1.1 mrg consume_data_flag = 0;
2303 1.1 mrg
2304 1.1 mrg dtp->u.p.skips += f->u.n;
2305 1.1 mrg pos = bytes_used + dtp->u.p.skips - 1;
2306 1.1 mrg dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
2307 1.1 mrg /* Writes occur just before the switch on f->format, above, so
2308 1.1 mrg that trailing blanks are suppressed, unless we are doing a
2309 1.1 mrg non-advancing write in which case we want to output the blanks
2310 1.1 mrg now. */
2311 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO)
2312 1.1 mrg {
2313 1.1 mrg write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
2314 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2315 1.1 mrg }
2316 1.1 mrg break;
2317 1.1 mrg
2318 1.1 mrg case FMT_TL:
2319 1.1 mrg case FMT_T:
2320 1.1 mrg consume_data_flag = 0;
2321 1.1 mrg
2322 1.1 mrg if (f->format == FMT_TL)
2323 1.1 mrg {
2324 1.1 mrg
2325 1.1 mrg /* Handle the special case when no bytes have been used yet.
2326 1.1 mrg Cannot go below zero. */
2327 1.1 mrg if (bytes_used == 0)
2328 1.1 mrg {
2329 1.1 mrg dtp->u.p.pending_spaces -= f->u.n;
2330 1.1 mrg dtp->u.p.skips -= f->u.n;
2331 1.1 mrg dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
2332 1.1 mrg }
2333 1.1 mrg
2334 1.1 mrg pos = bytes_used - f->u.n;
2335 1.1 mrg }
2336 1.1 mrg else /* FMT_T */
2337 1.1 mrg pos = f->u.n - dtp->u.p.pending_spaces - 1;
2338 1.1 mrg
2339 1.1 mrg /* Standard 10.6.1.1: excessive left tabbing is reset to the
2340 1.1 mrg left tab limit. We do not check if the position has gone
2341 1.1 mrg beyond the end of record because a subsequent tab could
2342 1.1 mrg bring us back again. */
2343 1.1 mrg pos = pos < 0 ? 0 : pos;
2344 1.1 mrg
2345 1.1 mrg dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
2346 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
2347 1.1 mrg + pos - dtp->u.p.max_pos;
2348 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
2349 1.1 mrg ? 0 : dtp->u.p.pending_spaces;
2350 1.1 mrg break;
2351 1.1 mrg
2352 1.1 mrg case FMT_S:
2353 1.1 mrg consume_data_flag = 0;
2354 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PROCDEFINED;
2355 1.1 mrg break;
2356 1.1 mrg
2357 1.1 mrg case FMT_SS:
2358 1.1 mrg consume_data_flag = 0;
2359 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_SUPPRESS;
2360 1.1 mrg break;
2361 1.1 mrg
2362 1.1 mrg case FMT_SP:
2363 1.1 mrg consume_data_flag = 0;
2364 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PLUS;
2365 1.1 mrg break;
2366 1.1 mrg
2367 1.1 mrg case FMT_BN:
2368 1.1 mrg consume_data_flag = 0 ;
2369 1.1 mrg dtp->u.p.blank_status = BLANK_NULL;
2370 1.1 mrg break;
2371 1.1 mrg
2372 1.1 mrg case FMT_BZ:
2373 1.1 mrg consume_data_flag = 0;
2374 1.1 mrg dtp->u.p.blank_status = BLANK_ZERO;
2375 1.1 mrg break;
2376 1.1 mrg
2377 1.1 mrg case FMT_DC:
2378 1.1 mrg consume_data_flag = 0;
2379 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
2380 1.1 mrg break;
2381 1.1 mrg
2382 1.1 mrg case FMT_DP:
2383 1.1 mrg consume_data_flag = 0;
2384 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
2385 1.1 mrg break;
2386 1.1 mrg
2387 1.1 mrg case FMT_RC:
2388 1.1 mrg consume_data_flag = 0;
2389 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
2390 1.1 mrg break;
2391 1.1 mrg
2392 1.1 mrg case FMT_RD:
2393 1.1 mrg consume_data_flag = 0;
2394 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_DOWN;
2395 1.1 mrg break;
2396 1.1 mrg
2397 1.1 mrg case FMT_RN:
2398 1.1 mrg consume_data_flag = 0;
2399 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_NEAREST;
2400 1.1 mrg break;
2401 1.1 mrg
2402 1.1 mrg case FMT_RP:
2403 1.1 mrg consume_data_flag = 0;
2404 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
2405 1.1 mrg break;
2406 1.1 mrg
2407 1.1 mrg case FMT_RU:
2408 1.1 mrg consume_data_flag = 0;
2409 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_UP;
2410 1.1 mrg break;
2411 1.1 mrg
2412 1.1 mrg case FMT_RZ:
2413 1.1 mrg consume_data_flag = 0;
2414 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_ZERO;
2415 1.1 mrg break;
2416 1.1 mrg
2417 1.1 mrg case FMT_P:
2418 1.1 mrg consume_data_flag = 0;
2419 1.1 mrg dtp->u.p.scale_factor = f->u.k;
2420 1.1 mrg break;
2421 1.1 mrg
2422 1.1 mrg case FMT_DOLLAR:
2423 1.1 mrg consume_data_flag = 0;
2424 1.1 mrg dtp->u.p.seen_dollar = 1;
2425 1.1 mrg break;
2426 1.1 mrg
2427 1.1 mrg case FMT_SLASH:
2428 1.1 mrg consume_data_flag = 0;
2429 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2430 1.1 mrg next_record (dtp, 0);
2431 1.1 mrg break;
2432 1.1 mrg
2433 1.1 mrg case FMT_COLON:
2434 1.1 mrg /* A colon descriptor causes us to exit this loop (in
2435 1.1 mrg particular preventing another / descriptor from being
2436 1.1 mrg processed) unless there is another data item to be
2437 1.1 mrg transferred. */
2438 1.1 mrg consume_data_flag = 0;
2439 1.1 mrg if (n == 0)
2440 1.1 mrg return;
2441 1.1 mrg break;
2442 1.1 mrg
2443 1.1 mrg default:
2444 1.1 mrg internal_error (&dtp->common, "Bad format node");
2445 1.1 mrg }
2446 1.1 mrg
2447 1.1 mrg /* Adjust the item count and data pointer. */
2448 1.1 mrg
2449 1.1 mrg if ((consume_data_flag > 0) && (n > 0))
2450 1.1 mrg {
2451 1.1 mrg n--;
2452 1.1 mrg p = ((char *) p) + size;
2453 1.1 mrg }
2454 1.1 mrg
2455 1.1 mrg pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left;
2456 1.1 mrg dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
2457 1.1 mrg }
2458 1.1 mrg
2459 1.1 mrg return;
2460 1.1 mrg
2461 1.1 mrg /* Come here when we need a data descriptor but don't have one. We
2462 1.1 mrg push the current format node back onto the input, then return and
2463 1.1 mrg let the user program call us back with the data. */
2464 1.1 mrg need_data:
2465 1.1 mrg unget_format (dtp, f);
2466 1.1 mrg }
2467 1.1 mrg
2468 1.1 mrg /* This function is first called from data_init_transfer to initiate the loop
2469 1.1 mrg over each item in the format, transferring data as required. Subsequent
2470 1.1 mrg calls to this function occur for each data item foound in the READ/WRITE
2471 1.1 mrg statement. The item_count is incremented for each call. Since the first
2472 1.1 mrg call is from data_transfer_init, the item_count is always one greater than
2473 1.1 mrg the actual count number of the item being transferred. */
2474 1.1 mrg
2475 1.1 mrg static void
2476 1.1 mrg formatted_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
2477 1.1 mrg size_t size, size_t nelems)
2478 1.1 mrg {
2479 1.1 mrg size_t elem;
2480 1.1 mrg char *tmp;
2481 1.1 mrg
2482 1.1 mrg tmp = (char *) p;
2483 1.1 mrg size_t stride = type == BT_CHARACTER ?
2484 1.1 mrg size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
2485 1.1 mrg if (dtp->u.p.mode == READING)
2486 1.1 mrg {
2487 1.1 mrg /* Big loop over all the elements. */
2488 1.1 mrg for (elem = 0; elem < nelems; elem++)
2489 1.1 mrg {
2490 1.1 mrg dtp->u.p.item_count++;
2491 1.1 mrg formatted_transfer_scalar_read (dtp, type, tmp + stride*elem, kind, size);
2492 1.1 mrg }
2493 1.1 mrg }
2494 1.1 mrg else
2495 1.1 mrg {
2496 1.1 mrg /* Big loop over all the elements. */
2497 1.1 mrg for (elem = 0; elem < nelems; elem++)
2498 1.1 mrg {
2499 1.1 mrg dtp->u.p.item_count++;
2500 1.1 mrg formatted_transfer_scalar_write (dtp, type, tmp + stride*elem, kind, size);
2501 1.1 mrg }
2502 1.1 mrg }
2503 1.1 mrg }
2504 1.1 mrg
2505 1.1 mrg /* Wrapper function for I/O of scalar types. If this should be an async I/O
2506 1.1 mrg request, queue it. For a synchronous write on an async unit, perform the
2507 1.1 mrg wait operation and return an error. For all synchronous writes, call the
2508 1.1 mrg right transfer function. */
2509 1.1 mrg
2510 1.1 mrg static void
2511 1.1 mrg wrap_scalar_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
2512 1.1 mrg size_t size, size_t n_elem)
2513 1.1 mrg {
2514 1.1 mrg if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
2515 1.1 mrg {
2516 1.1 mrg if (dtp->u.p.async)
2517 1.1 mrg {
2518 1.1 mrg transfer_args args;
2519 1.1 mrg args.scalar.transfer = dtp->u.p.transfer;
2520 1.1 mrg args.scalar.arg_bt = type;
2521 1.1 mrg args.scalar.data = p;
2522 1.1 mrg args.scalar.i = kind;
2523 1.1 mrg args.scalar.s1 = size;
2524 1.1 mrg args.scalar.s2 = n_elem;
2525 1.1 mrg enqueue_transfer (dtp->u.p.current_unit->au, &args,
2526 1.1 mrg AIO_TRANSFER_SCALAR);
2527 1.1 mrg return;
2528 1.1 mrg }
2529 1.1 mrg }
2530 1.1 mrg /* Come here if there was no asynchronous I/O to be scheduled. */
2531 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2532 1.1 mrg return;
2533 1.1 mrg
2534 1.1 mrg dtp->u.p.transfer (dtp, type, p, kind, size, 1);
2535 1.1 mrg }
2536 1.1 mrg
2537 1.1 mrg
2538 1.1 mrg /* Data transfer entry points. The type of the data entity is
2539 1.1 mrg implicit in the subroutine call. This prevents us from having to
2540 1.1 mrg share a common enum with the compiler. */
2541 1.1 mrg
2542 1.1 mrg void
2543 1.1 mrg transfer_integer (st_parameter_dt *dtp, void *p, int kind)
2544 1.1 mrg {
2545 1.1 mrg wrap_scalar_transfer (dtp, BT_INTEGER, p, kind, kind, 1);
2546 1.1 mrg }
2547 1.1 mrg
2548 1.1 mrg void
2549 1.1 mrg transfer_integer_write (st_parameter_dt *dtp, void *p, int kind)
2550 1.1 mrg {
2551 1.1 mrg transfer_integer (dtp, p, kind);
2552 1.1 mrg }
2553 1.1 mrg
2554 1.1 mrg void
2555 1.1 mrg transfer_real (st_parameter_dt *dtp, void *p, int kind)
2556 1.1 mrg {
2557 1.1 mrg size_t size;
2558 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2559 1.1 mrg return;
2560 1.1 mrg size = size_from_real_kind (kind);
2561 1.1 mrg wrap_scalar_transfer (dtp, BT_REAL, p, kind, size, 1);
2562 1.1 mrg }
2563 1.1 mrg
2564 1.1 mrg void
2565 1.1 mrg transfer_real_write (st_parameter_dt *dtp, void *p, int kind)
2566 1.1 mrg {
2567 1.1 mrg transfer_real (dtp, p, kind);
2568 1.1 mrg }
2569 1.1 mrg
2570 1.1 mrg void
2571 1.1 mrg transfer_logical (st_parameter_dt *dtp, void *p, int kind)
2572 1.1 mrg {
2573 1.1 mrg wrap_scalar_transfer (dtp, BT_LOGICAL, p, kind, kind, 1);
2574 1.1 mrg }
2575 1.1 mrg
2576 1.1 mrg void
2577 1.1 mrg transfer_logical_write (st_parameter_dt *dtp, void *p, int kind)
2578 1.1 mrg {
2579 1.1 mrg transfer_logical (dtp, p, kind);
2580 1.1 mrg }
2581 1.1 mrg
2582 1.1 mrg void
2583 1.1 mrg transfer_character (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
2584 1.1 mrg {
2585 1.1 mrg static char *empty_string[0];
2586 1.1 mrg
2587 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2588 1.1 mrg return;
2589 1.1 mrg
2590 1.1 mrg /* Strings of zero length can have p == NULL, which confuses the
2591 1.1 mrg transfer routines into thinking we need more data elements. To avoid
2592 1.1 mrg this, we give them a nice pointer. */
2593 1.1 mrg if (len == 0 && p == NULL)
2594 1.1 mrg p = empty_string;
2595 1.1 mrg
2596 1.1 mrg /* Set kind here to 1. */
2597 1.1 mrg wrap_scalar_transfer (dtp, BT_CHARACTER, p, 1, len, 1);
2598 1.1 mrg }
2599 1.1 mrg
2600 1.1 mrg void
2601 1.1 mrg transfer_character_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
2602 1.1 mrg {
2603 1.1 mrg transfer_character (dtp, p, len);
2604 1.1 mrg }
2605 1.1 mrg
2606 1.1 mrg void
2607 1.1 mrg transfer_character_wide (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
2608 1.1 mrg {
2609 1.1 mrg static char *empty_string[0];
2610 1.1 mrg
2611 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2612 1.1 mrg return;
2613 1.1 mrg
2614 1.1 mrg /* Strings of zero length can have p == NULL, which confuses the
2615 1.1 mrg transfer routines into thinking we need more data elements. To avoid
2616 1.1 mrg this, we give them a nice pointer. */
2617 1.1 mrg if (len == 0 && p == NULL)
2618 1.1 mrg p = empty_string;
2619 1.1 mrg
2620 1.1 mrg /* Here we pass the actual kind value. */
2621 1.1 mrg wrap_scalar_transfer (dtp, BT_CHARACTER, p, kind, len, 1);
2622 1.1 mrg }
2623 1.1 mrg
2624 1.1 mrg void
2625 1.1 mrg transfer_character_wide_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
2626 1.1 mrg {
2627 1.1 mrg transfer_character_wide (dtp, p, len, kind);
2628 1.1 mrg }
2629 1.1 mrg
2630 1.1 mrg void
2631 1.1 mrg transfer_complex (st_parameter_dt *dtp, void *p, int kind)
2632 1.1 mrg {
2633 1.1 mrg size_t size;
2634 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2635 1.1 mrg return;
2636 1.1 mrg size = size_from_complex_kind (kind);
2637 1.1 mrg wrap_scalar_transfer (dtp, BT_COMPLEX, p, kind, size, 1);
2638 1.1 mrg }
2639 1.1 mrg
2640 1.1 mrg void
2641 1.1 mrg transfer_complex_write (st_parameter_dt *dtp, void *p, int kind)
2642 1.1 mrg {
2643 1.1 mrg transfer_complex (dtp, p, kind);
2644 1.1 mrg }
2645 1.1 mrg
2646 1.1 mrg void
2647 1.1 mrg transfer_array_inner (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
2648 1.1 mrg gfc_charlen_type charlen)
2649 1.1 mrg {
2650 1.1 mrg index_type count[GFC_MAX_DIMENSIONS];
2651 1.1 mrg index_type extent[GFC_MAX_DIMENSIONS];
2652 1.1 mrg index_type stride[GFC_MAX_DIMENSIONS];
2653 1.1 mrg index_type stride0, rank, size, n;
2654 1.1 mrg size_t tsize;
2655 1.1 mrg char *data;
2656 1.1 mrg bt iotype;
2657 1.1 mrg
2658 1.1 mrg /* Adjust item_count before emitting error message. */
2659 1.1 mrg
2660 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2661 1.1 mrg return;
2662 1.1 mrg
2663 1.1 mrg iotype = (bt) GFC_DESCRIPTOR_TYPE (desc);
2664 1.1 mrg size = iotype == BT_CHARACTER ? charlen : GFC_DESCRIPTOR_SIZE (desc);
2665 1.1 mrg
2666 1.1 mrg rank = GFC_DESCRIPTOR_RANK (desc);
2667 1.1 mrg
2668 1.1 mrg for (n = 0; n < rank; n++)
2669 1.1 mrg {
2670 1.1 mrg count[n] = 0;
2671 1.1 mrg stride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(desc,n);
2672 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(desc,n);
2673 1.1 mrg
2674 1.1 mrg /* If the extent of even one dimension is zero, then the entire
2675 1.1 mrg array section contains zero elements, so we return after writing
2676 1.1 mrg a zero array record. */
2677 1.1 mrg if (extent[n] <= 0)
2678 1.1 mrg {
2679 1.1 mrg data = NULL;
2680 1.1 mrg tsize = 0;
2681 1.1 mrg dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
2682 1.1 mrg return;
2683 1.1 mrg }
2684 1.1 mrg }
2685 1.1 mrg
2686 1.1 mrg stride0 = stride[0];
2687 1.1 mrg
2688 1.1 mrg /* If the innermost dimension has a stride of 1, we can do the transfer
2689 1.1 mrg in contiguous chunks. */
2690 1.1 mrg if (stride0 == size)
2691 1.1 mrg tsize = extent[0];
2692 1.1 mrg else
2693 1.1 mrg tsize = 1;
2694 1.1 mrg
2695 1.1 mrg data = GFC_DESCRIPTOR_DATA (desc);
2696 1.1 mrg
2697 1.1 mrg /* When reading, we need to check endfile conditions so we do not miss
2698 1.1 mrg an END=label. Make this separate so we do not have an extra test
2699 1.1 mrg in a tight loop when it is not needed. */
2700 1.1 mrg
2701 1.1 mrg if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
2702 1.1 mrg {
2703 1.1 mrg while (data)
2704 1.1 mrg {
2705 1.1 mrg if (unlikely (dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
2706 1.1 mrg return;
2707 1.1 mrg
2708 1.1 mrg dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
2709 1.1 mrg data += stride0 * tsize;
2710 1.1 mrg count[0] += tsize;
2711 1.1 mrg n = 0;
2712 1.1 mrg while (count[n] == extent[n])
2713 1.1 mrg {
2714 1.1 mrg count[n] = 0;
2715 1.1 mrg data -= stride[n] * extent[n];
2716 1.1 mrg n++;
2717 1.1 mrg if (n == rank)
2718 1.1 mrg {
2719 1.1 mrg data = NULL;
2720 1.1 mrg break;
2721 1.1 mrg }
2722 1.1 mrg else
2723 1.1 mrg {
2724 1.1 mrg count[n]++;
2725 1.1 mrg data += stride[n];
2726 1.1 mrg }
2727 1.1 mrg }
2728 1.1 mrg }
2729 1.1 mrg }
2730 1.1 mrg else
2731 1.1 mrg {
2732 1.1 mrg while (data)
2733 1.1 mrg {
2734 1.1 mrg dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
2735 1.1 mrg data += stride0 * tsize;
2736 1.1 mrg count[0] += tsize;
2737 1.1 mrg n = 0;
2738 1.1 mrg while (count[n] == extent[n])
2739 1.1 mrg {
2740 1.1 mrg count[n] = 0;
2741 1.1 mrg data -= stride[n] * extent[n];
2742 1.1 mrg n++;
2743 1.1 mrg if (n == rank)
2744 1.1 mrg {
2745 1.1 mrg data = NULL;
2746 1.1 mrg break;
2747 1.1 mrg }
2748 1.1 mrg else
2749 1.1 mrg {
2750 1.1 mrg count[n]++;
2751 1.1 mrg data += stride[n];
2752 1.1 mrg }
2753 1.1 mrg }
2754 1.1 mrg }
2755 1.1 mrg }
2756 1.1 mrg }
2757 1.1 mrg
2758 1.1 mrg void
2759 1.1 mrg transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
2760 1.1 mrg gfc_charlen_type charlen)
2761 1.1 mrg {
2762 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2763 1.1 mrg return;
2764 1.1 mrg
2765 1.1 mrg if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
2766 1.1 mrg {
2767 1.1 mrg if (dtp->u.p.async)
2768 1.1 mrg {
2769 1.1 mrg transfer_args args;
2770 1.1 mrg size_t sz = sizeof (gfc_array_char)
2771 1.1 mrg + sizeof (descriptor_dimension)
2772 1.1 mrg * GFC_DESCRIPTOR_RANK (desc);
2773 1.1 mrg args.array.desc = xmalloc (sz);
2774 1.1 mrg NOTE ("desc = %p", (void *) args.array.desc);
2775 1.1 mrg memcpy (args.array.desc, desc, sz);
2776 1.1 mrg args.array.kind = kind;
2777 1.1 mrg args.array.charlen = charlen;
2778 1.1 mrg enqueue_transfer (dtp->u.p.current_unit->au, &args,
2779 1.1 mrg AIO_TRANSFER_ARRAY);
2780 1.1 mrg return;
2781 1.1 mrg }
2782 1.1 mrg }
2783 1.1 mrg /* Come here if there was no asynchronous I/O to be scheduled. */
2784 1.1 mrg transfer_array_inner (dtp, desc, kind, charlen);
2785 1.1 mrg }
2786 1.1 mrg
2787 1.1 mrg
2788 1.1 mrg void
2789 1.1 mrg transfer_array_write (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
2790 1.1 mrg gfc_charlen_type charlen)
2791 1.1 mrg {
2792 1.1 mrg transfer_array (dtp, desc, kind, charlen);
2793 1.1 mrg }
2794 1.1 mrg
2795 1.1 mrg
2796 1.1 mrg /* User defined input/output iomsg. */
2797 1.1 mrg
2798 1.1 mrg #define IOMSG_LEN 256
2799 1.1 mrg
2800 1.1 mrg void
2801 1.1 mrg transfer_derived (st_parameter_dt *parent, void *dtio_source, void *dtio_proc)
2802 1.1 mrg {
2803 1.1 mrg if (parent->u.p.current_unit)
2804 1.1 mrg {
2805 1.1 mrg if (parent->u.p.current_unit->flags.form == FORM_UNFORMATTED)
2806 1.1 mrg parent->u.p.ufdtio_ptr = (unformatted_dtio) dtio_proc;
2807 1.1 mrg else
2808 1.1 mrg parent->u.p.fdtio_ptr = (formatted_dtio) dtio_proc;
2809 1.1 mrg }
2810 1.1 mrg wrap_scalar_transfer (parent, BT_CLASS, dtio_source, 0, 0, 1);
2811 1.1 mrg }
2812 1.1 mrg
2813 1.1 mrg
2814 1.1 mrg /* Preposition a sequential unformatted file while reading. */
2815 1.1 mrg
2816 1.1 mrg static void
2817 1.1 mrg us_read (st_parameter_dt *dtp, int continued)
2818 1.1 mrg {
2819 1.1 mrg ssize_t n, nr;
2820 1.1 mrg GFC_INTEGER_4 i4;
2821 1.1 mrg GFC_INTEGER_8 i8;
2822 1.1 mrg gfc_offset i;
2823 1.1 mrg
2824 1.1 mrg if (compile_options.record_marker == 0)
2825 1.1 mrg n = sizeof (GFC_INTEGER_4);
2826 1.1 mrg else
2827 1.1 mrg n = compile_options.record_marker;
2828 1.1 mrg
2829 1.1 mrg nr = sread (dtp->u.p.current_unit->s, &i, n);
2830 1.1 mrg if (unlikely (nr < 0))
2831 1.1 mrg {
2832 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
2833 1.1 mrg return;
2834 1.1 mrg }
2835 1.1 mrg else if (nr == 0)
2836 1.1 mrg {
2837 1.1 mrg hit_eof (dtp);
2838 1.1 mrg return; /* end of file */
2839 1.1 mrg }
2840 1.1 mrg else if (unlikely (n != nr))
2841 1.1 mrg {
2842 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
2843 1.1 mrg return;
2844 1.1 mrg }
2845 1.1 mrg
2846 1.1.1.3 mrg int convert = dtp->u.p.current_unit->flags.convert;
2847 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
2848 1.1.1.3 mrg convert &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
2849 1.1.1.3 mrg #endif
2850 1.1 mrg /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
2851 1.1.1.3 mrg if (likely (convert == GFC_CONVERT_NATIVE))
2852 1.1 mrg {
2853 1.1 mrg switch (nr)
2854 1.1 mrg {
2855 1.1 mrg case sizeof(GFC_INTEGER_4):
2856 1.1 mrg memcpy (&i4, &i, sizeof (i4));
2857 1.1 mrg i = i4;
2858 1.1 mrg break;
2859 1.1 mrg
2860 1.1 mrg case sizeof(GFC_INTEGER_8):
2861 1.1 mrg memcpy (&i8, &i, sizeof (i8));
2862 1.1 mrg i = i8;
2863 1.1 mrg break;
2864 1.1 mrg
2865 1.1 mrg default:
2866 1.1 mrg runtime_error ("Illegal value for record marker");
2867 1.1 mrg break;
2868 1.1 mrg }
2869 1.1 mrg }
2870 1.1 mrg else
2871 1.1 mrg {
2872 1.1 mrg uint32_t u32;
2873 1.1 mrg uint64_t u64;
2874 1.1 mrg switch (nr)
2875 1.1 mrg {
2876 1.1 mrg case sizeof(GFC_INTEGER_4):
2877 1.1 mrg memcpy (&u32, &i, sizeof (u32));
2878 1.1 mrg u32 = __builtin_bswap32 (u32);
2879 1.1 mrg memcpy (&i4, &u32, sizeof (i4));
2880 1.1 mrg i = i4;
2881 1.1 mrg break;
2882 1.1 mrg
2883 1.1 mrg case sizeof(GFC_INTEGER_8):
2884 1.1 mrg memcpy (&u64, &i, sizeof (u64));
2885 1.1 mrg u64 = __builtin_bswap64 (u64);
2886 1.1 mrg memcpy (&i8, &u64, sizeof (i8));
2887 1.1 mrg i = i8;
2888 1.1 mrg break;
2889 1.1 mrg
2890 1.1 mrg default:
2891 1.1 mrg runtime_error ("Illegal value for record marker");
2892 1.1 mrg break;
2893 1.1 mrg }
2894 1.1 mrg }
2895 1.1 mrg
2896 1.1 mrg if (i >= 0)
2897 1.1 mrg {
2898 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord = i;
2899 1.1 mrg dtp->u.p.current_unit->continued = 0;
2900 1.1 mrg }
2901 1.1 mrg else
2902 1.1 mrg {
2903 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord = -i;
2904 1.1 mrg dtp->u.p.current_unit->continued = 1;
2905 1.1 mrg }
2906 1.1 mrg
2907 1.1 mrg if (! continued)
2908 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2909 1.1 mrg }
2910 1.1 mrg
2911 1.1 mrg
2912 1.1 mrg /* Preposition a sequential unformatted file while writing. This
2913 1.1 mrg amount to writing a bogus length that will be filled in later. */
2914 1.1 mrg
2915 1.1 mrg static void
2916 1.1 mrg us_write (st_parameter_dt *dtp, int continued)
2917 1.1 mrg {
2918 1.1 mrg ssize_t nbytes;
2919 1.1 mrg gfc_offset dummy;
2920 1.1 mrg
2921 1.1 mrg dummy = 0;
2922 1.1 mrg
2923 1.1 mrg if (compile_options.record_marker == 0)
2924 1.1 mrg nbytes = sizeof (GFC_INTEGER_4);
2925 1.1 mrg else
2926 1.1 mrg nbytes = compile_options.record_marker ;
2927 1.1 mrg
2928 1.1 mrg if (swrite (dtp->u.p.current_unit->s, &dummy, nbytes) != nbytes)
2929 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
2930 1.1 mrg
2931 1.1 mrg /* For sequential unformatted, if RECL= was not specified in the OPEN
2932 1.1 mrg we write until we have more bytes than can fit in the subrecord
2933 1.1 mrg markers, then we write a new subrecord. */
2934 1.1 mrg
2935 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord =
2936 1.1 mrg dtp->u.p.current_unit->recl_subrecord;
2937 1.1 mrg dtp->u.p.current_unit->continued = continued;
2938 1.1 mrg }
2939 1.1 mrg
2940 1.1 mrg
2941 1.1 mrg /* Position to the next record prior to transfer. We are assumed to
2942 1.1 mrg be before the next record. We also calculate the bytes in the next
2943 1.1 mrg record. */
2944 1.1 mrg
2945 1.1 mrg static void
2946 1.1 mrg pre_position (st_parameter_dt *dtp)
2947 1.1 mrg {
2948 1.1 mrg if (dtp->u.p.current_unit->current_record)
2949 1.1 mrg return; /* Already positioned. */
2950 1.1 mrg
2951 1.1 mrg switch (current_mode (dtp))
2952 1.1 mrg {
2953 1.1 mrg case FORMATTED_STREAM:
2954 1.1 mrg case UNFORMATTED_STREAM:
2955 1.1 mrg /* There are no records with stream I/O. If the position was specified
2956 1.1 mrg data_transfer_init has already positioned the file. If no position
2957 1.1 mrg was specified, we continue from where we last left off. I.e.
2958 1.1 mrg there is nothing to do here. */
2959 1.1 mrg break;
2960 1.1 mrg
2961 1.1 mrg case UNFORMATTED_SEQUENTIAL:
2962 1.1 mrg if (dtp->u.p.mode == READING)
2963 1.1 mrg us_read (dtp, 0);
2964 1.1 mrg else
2965 1.1 mrg us_write (dtp, 0);
2966 1.1 mrg
2967 1.1 mrg break;
2968 1.1 mrg
2969 1.1 mrg case FORMATTED_SEQUENTIAL:
2970 1.1 mrg case FORMATTED_DIRECT:
2971 1.1 mrg case UNFORMATTED_DIRECT:
2972 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2973 1.1 mrg break;
2974 1.1.1.2 mrg case FORMATTED_UNSPECIFIED:
2975 1.1.1.2 mrg gcc_unreachable ();
2976 1.1 mrg }
2977 1.1 mrg
2978 1.1 mrg dtp->u.p.current_unit->current_record = 1;
2979 1.1 mrg }
2980 1.1 mrg
2981 1.1 mrg
2982 1.1 mrg /* Initialize things for a data transfer. This code is common for
2983 1.1 mrg both reading and writing. */
2984 1.1 mrg
2985 1.1 mrg static void
2986 1.1 mrg data_transfer_init (st_parameter_dt *dtp, int read_flag)
2987 1.1 mrg {
2988 1.1 mrg unit_flags u_flags; /* Used for creating a unit if needed. */
2989 1.1 mrg GFC_INTEGER_4 cf = dtp->common.flags;
2990 1.1 mrg namelist_info *ionml;
2991 1.1 mrg async_unit *au;
2992 1.1 mrg
2993 1.1 mrg NOTE ("data_transfer_init");
2994 1.1 mrg
2995 1.1 mrg ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL;
2996 1.1 mrg
2997 1.1 mrg memset (&dtp->u.p, 0, sizeof (dtp->u.p));
2998 1.1 mrg
2999 1.1 mrg dtp->u.p.ionml = ionml;
3000 1.1 mrg dtp->u.p.mode = read_flag ? READING : WRITING;
3001 1.1 mrg dtp->u.p.namelist_mode = 0;
3002 1.1 mrg dtp->u.p.cc.len = 0;
3003 1.1 mrg
3004 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
3005 1.1 mrg return;
3006 1.1 mrg
3007 1.1 mrg dtp->u.p.current_unit = get_unit (dtp, 1);
3008 1.1 mrg
3009 1.1 mrg if (dtp->u.p.current_unit == NULL)
3010 1.1 mrg {
3011 1.1 mrg /* This means we tried to access an external unit < 0 without
3012 1.1 mrg having opened it first with NEWUNIT=. */
3013 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3014 1.1 mrg "Unit number is negative and unit was not already "
3015 1.1 mrg "opened with OPEN(NEWUNIT=...)");
3016 1.1 mrg return;
3017 1.1 mrg }
3018 1.1 mrg else if (dtp->u.p.current_unit->s == NULL)
3019 1.1 mrg { /* Open the unit with some default flags. */
3020 1.1 mrg st_parameter_open opp;
3021 1.1 mrg unit_convert conv;
3022 1.1 mrg NOTE ("Open the unit with some default flags.");
3023 1.1 mrg memset (&u_flags, '\0', sizeof (u_flags));
3024 1.1 mrg u_flags.access = ACCESS_SEQUENTIAL;
3025 1.1 mrg u_flags.action = ACTION_READWRITE;
3026 1.1 mrg
3027 1.1 mrg /* Is it unformatted? */
3028 1.1 mrg if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
3029 1.1 mrg | IOPARM_DT_IONML_SET)))
3030 1.1 mrg u_flags.form = FORM_UNFORMATTED;
3031 1.1 mrg else
3032 1.1 mrg u_flags.form = FORM_UNSPECIFIED;
3033 1.1 mrg
3034 1.1 mrg u_flags.delim = DELIM_UNSPECIFIED;
3035 1.1 mrg u_flags.blank = BLANK_UNSPECIFIED;
3036 1.1 mrg u_flags.pad = PAD_UNSPECIFIED;
3037 1.1 mrg u_flags.decimal = DECIMAL_UNSPECIFIED;
3038 1.1 mrg u_flags.encoding = ENCODING_UNSPECIFIED;
3039 1.1 mrg u_flags.async = ASYNC_UNSPECIFIED;
3040 1.1 mrg u_flags.round = ROUND_UNSPECIFIED;
3041 1.1 mrg u_flags.sign = SIGN_UNSPECIFIED;
3042 1.1 mrg u_flags.share = SHARE_UNSPECIFIED;
3043 1.1 mrg u_flags.cc = CC_UNSPECIFIED;
3044 1.1 mrg u_flags.readonly = 0;
3045 1.1 mrg
3046 1.1 mrg u_flags.status = STATUS_UNKNOWN;
3047 1.1 mrg
3048 1.1 mrg conv = get_unformatted_convert (dtp->common.unit);
3049 1.1 mrg
3050 1.1 mrg if (conv == GFC_CONVERT_NONE)
3051 1.1 mrg conv = compile_options.convert;
3052 1.1 mrg
3053 1.1.1.3 mrg u_flags.convert = 0;
3054 1.1.1.3 mrg
3055 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
3056 1.1.1.3 mrg u_flags.convert = conv & (GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
3057 1.1.1.3 mrg conv &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
3058 1.1.1.3 mrg #endif
3059 1.1.1.3 mrg
3060 1.1 mrg switch (conv)
3061 1.1 mrg {
3062 1.1 mrg case GFC_CONVERT_NATIVE:
3063 1.1 mrg case GFC_CONVERT_SWAP:
3064 1.1 mrg break;
3065 1.1 mrg
3066 1.1 mrg case GFC_CONVERT_BIG:
3067 1.1 mrg conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
3068 1.1 mrg break;
3069 1.1 mrg
3070 1.1 mrg case GFC_CONVERT_LITTLE:
3071 1.1 mrg conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
3072 1.1 mrg break;
3073 1.1 mrg
3074 1.1 mrg default:
3075 1.1 mrg internal_error (&opp.common, "Illegal value for CONVERT");
3076 1.1 mrg break;
3077 1.1 mrg }
3078 1.1 mrg
3079 1.1.1.3 mrg u_flags.convert |= conv;
3080 1.1 mrg
3081 1.1 mrg opp.common = dtp->common;
3082 1.1 mrg opp.common.flags &= IOPARM_COMMON_MASK;
3083 1.1 mrg dtp->u.p.current_unit = new_unit (&opp, dtp->u.p.current_unit, &u_flags);
3084 1.1 mrg dtp->common.flags &= ~IOPARM_COMMON_MASK;
3085 1.1 mrg dtp->common.flags |= (opp.common.flags & IOPARM_COMMON_MASK);
3086 1.1 mrg if (dtp->u.p.current_unit == NULL)
3087 1.1 mrg return;
3088 1.1 mrg }
3089 1.1 mrg
3090 1.1 mrg if (dtp->u.p.current_unit->child_dtio == 0)
3091 1.1 mrg {
3092 1.1 mrg if ((cf & IOPARM_DT_HAS_SIZE) != 0)
3093 1.1 mrg {
3094 1.1 mrg dtp->u.p.current_unit->has_size = true;
3095 1.1 mrg /* Initialize the count. */
3096 1.1 mrg dtp->u.p.current_unit->size_used = 0;
3097 1.1 mrg }
3098 1.1 mrg else
3099 1.1 mrg dtp->u.p.current_unit->has_size = false;
3100 1.1 mrg }
3101 1.1 mrg else if (dtp->u.p.current_unit->internal_unit_kind > 0)
3102 1.1 mrg dtp->u.p.unit_is_internal = 1;
3103 1.1 mrg
3104 1.1 mrg if ((cf & IOPARM_DT_HAS_ASYNCHRONOUS) != 0)
3105 1.1 mrg {
3106 1.1 mrg int f;
3107 1.1 mrg f = find_option (&dtp->common, dtp->asynchronous, dtp->asynchronous_len,
3108 1.1 mrg async_opt, "Bad ASYNCHRONOUS in data transfer "
3109 1.1 mrg "statement");
3110 1.1 mrg if (f == ASYNC_YES && dtp->u.p.current_unit->flags.async != ASYNC_YES)
3111 1.1 mrg {
3112 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3113 1.1 mrg "ASYNCHRONOUS transfer without "
3114 1.1 mrg "ASYHCRONOUS='YES' in OPEN");
3115 1.1 mrg return;
3116 1.1 mrg }
3117 1.1 mrg dtp->u.p.async = f == ASYNC_YES;
3118 1.1 mrg }
3119 1.1 mrg
3120 1.1 mrg au = dtp->u.p.current_unit->au;
3121 1.1 mrg if (au)
3122 1.1 mrg {
3123 1.1 mrg if (dtp->u.p.async)
3124 1.1 mrg {
3125 1.1 mrg /* If this is an asynchronous I/O statement, collect errors and
3126 1.1 mrg return if there are any. */
3127 1.1 mrg if (collect_async_errors (&dtp->common, au))
3128 1.1 mrg return;
3129 1.1 mrg }
3130 1.1 mrg else
3131 1.1 mrg {
3132 1.1 mrg /* Synchronous statement: Perform a wait operation for any pending
3133 1.1 mrg asynchronous I/O. This needs to be done before all other error
3134 1.1 mrg checks. See F2008, 9.6.4.1. */
3135 1.1 mrg if (async_wait (&(dtp->common), au))
3136 1.1 mrg return;
3137 1.1 mrg }
3138 1.1 mrg }
3139 1.1 mrg
3140 1.1 mrg /* Check the action. */
3141 1.1 mrg
3142 1.1 mrg if (read_flag && dtp->u.p.current_unit->flags.action == ACTION_WRITE)
3143 1.1 mrg {
3144 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_ACTION,
3145 1.1 mrg "Cannot read from file opened for WRITE");
3146 1.1 mrg return;
3147 1.1 mrg }
3148 1.1 mrg
3149 1.1 mrg if (!read_flag && dtp->u.p.current_unit->flags.action == ACTION_READ)
3150 1.1 mrg {
3151 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_ACTION,
3152 1.1 mrg "Cannot write to file opened for READ");
3153 1.1 mrg return;
3154 1.1 mrg }
3155 1.1 mrg
3156 1.1 mrg dtp->u.p.first_item = 1;
3157 1.1 mrg
3158 1.1 mrg /* Check the format. */
3159 1.1 mrg
3160 1.1 mrg if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
3161 1.1 mrg parse_format (dtp);
3162 1.1 mrg
3163 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
3164 1.1 mrg && (cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
3165 1.1 mrg != 0)
3166 1.1 mrg {
3167 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3168 1.1 mrg "Format present for UNFORMATTED data transfer");
3169 1.1 mrg return;
3170 1.1 mrg }
3171 1.1 mrg
3172 1.1 mrg if ((cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0 && dtp->u.p.ionml != NULL)
3173 1.1 mrg {
3174 1.1 mrg if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
3175 1.1 mrg {
3176 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3177 1.1 mrg "A format cannot be specified with a namelist");
3178 1.1 mrg return;
3179 1.1 mrg }
3180 1.1 mrg }
3181 1.1 mrg else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
3182 1.1 mrg !(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT)))
3183 1.1 mrg {
3184 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3185 1.1 mrg "Missing format for FORMATTED data transfer");
3186 1.1 mrg return;
3187 1.1 mrg }
3188 1.1 mrg
3189 1.1 mrg if (is_internal_unit (dtp)
3190 1.1 mrg && dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
3191 1.1 mrg {
3192 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3193 1.1 mrg "Internal file cannot be accessed by UNFORMATTED "
3194 1.1 mrg "data transfer");
3195 1.1 mrg return;
3196 1.1 mrg }
3197 1.1 mrg
3198 1.1 mrg /* Check the record or position number. */
3199 1.1 mrg
3200 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT
3201 1.1 mrg && (cf & IOPARM_DT_HAS_REC) == 0)
3202 1.1 mrg {
3203 1.1 mrg generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
3204 1.1 mrg "Direct access data transfer requires record number");
3205 1.1 mrg return;
3206 1.1 mrg }
3207 1.1 mrg
3208 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
3209 1.1 mrg {
3210 1.1 mrg if ((cf & IOPARM_DT_HAS_REC) != 0)
3211 1.1 mrg {
3212 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3213 1.1 mrg "Record number not allowed for sequential access "
3214 1.1 mrg "data transfer");
3215 1.1 mrg return;
3216 1.1 mrg }
3217 1.1 mrg
3218 1.1 mrg if (compile_options.warn_std &&
3219 1.1 mrg dtp->u.p.current_unit->endfile == AFTER_ENDFILE)
3220 1.1 mrg {
3221 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3222 1.1 mrg "Sequential READ or WRITE not allowed after "
3223 1.1 mrg "EOF marker, possibly use REWIND or BACKSPACE");
3224 1.1 mrg return;
3225 1.1 mrg }
3226 1.1 mrg }
3227 1.1 mrg
3228 1.1 mrg /* Process the ADVANCE option. */
3229 1.1 mrg
3230 1.1 mrg dtp->u.p.advance_status
3231 1.1 mrg = !(cf & IOPARM_DT_HAS_ADVANCE) ? ADVANCE_UNSPECIFIED :
3232 1.1 mrg find_option (&dtp->common, dtp->advance, dtp->advance_len, advance_opt,
3233 1.1 mrg "Bad ADVANCE parameter in data transfer statement");
3234 1.1 mrg
3235 1.1 mrg if (dtp->u.p.advance_status != ADVANCE_UNSPECIFIED)
3236 1.1 mrg {
3237 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
3238 1.1 mrg {
3239 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3240 1.1 mrg "ADVANCE specification conflicts with sequential "
3241 1.1 mrg "access");
3242 1.1 mrg return;
3243 1.1 mrg }
3244 1.1 mrg
3245 1.1 mrg if (is_internal_unit (dtp))
3246 1.1 mrg {
3247 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3248 1.1 mrg "ADVANCE specification conflicts with internal file");
3249 1.1 mrg return;
3250 1.1 mrg }
3251 1.1 mrg
3252 1.1 mrg if ((cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
3253 1.1 mrg != IOPARM_DT_HAS_FORMAT)
3254 1.1 mrg {
3255 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3256 1.1 mrg "ADVANCE specification requires an explicit format");
3257 1.1 mrg return;
3258 1.1 mrg }
3259 1.1 mrg }
3260 1.1 mrg
3261 1.1 mrg /* Child IO is non-advancing and any ADVANCE= specifier is ignored.
3262 1.1 mrg F2008 9.6.2.4 */
3263 1.1 mrg if (dtp->u.p.current_unit->child_dtio > 0)
3264 1.1 mrg dtp->u.p.advance_status = ADVANCE_NO;
3265 1.1 mrg
3266 1.1 mrg if (read_flag)
3267 1.1 mrg {
3268 1.1 mrg dtp->u.p.current_unit->previous_nonadvancing_write = 0;
3269 1.1 mrg
3270 1.1 mrg if ((cf & IOPARM_EOR) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
3271 1.1 mrg {
3272 1.1 mrg generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
3273 1.1 mrg "EOR specification requires an ADVANCE specification "
3274 1.1 mrg "of NO");
3275 1.1 mrg return;
3276 1.1 mrg }
3277 1.1 mrg
3278 1.1 mrg if ((cf & IOPARM_DT_HAS_SIZE) != 0
3279 1.1 mrg && dtp->u.p.advance_status != ADVANCE_NO)
3280 1.1 mrg {
3281 1.1 mrg generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
3282 1.1 mrg "SIZE specification requires an ADVANCE "
3283 1.1 mrg "specification of NO");
3284 1.1 mrg return;
3285 1.1 mrg }
3286 1.1 mrg }
3287 1.1 mrg else
3288 1.1 mrg { /* Write constraints. */
3289 1.1 mrg if ((cf & IOPARM_END) != 0)
3290 1.1 mrg {
3291 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3292 1.1 mrg "END specification cannot appear in a write "
3293 1.1 mrg "statement");
3294 1.1 mrg return;
3295 1.1 mrg }
3296 1.1 mrg
3297 1.1 mrg if ((cf & IOPARM_EOR) != 0)
3298 1.1 mrg {
3299 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3300 1.1 mrg "EOR specification cannot appear in a write "
3301 1.1 mrg "statement");
3302 1.1 mrg return;
3303 1.1 mrg }
3304 1.1 mrg
3305 1.1 mrg if ((cf & IOPARM_DT_HAS_SIZE) != 0)
3306 1.1 mrg {
3307 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3308 1.1 mrg "SIZE specification cannot appear in a write "
3309 1.1 mrg "statement");
3310 1.1 mrg return;
3311 1.1 mrg }
3312 1.1 mrg }
3313 1.1 mrg
3314 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_UNSPECIFIED)
3315 1.1 mrg dtp->u.p.advance_status = ADVANCE_YES;
3316 1.1 mrg
3317 1.1 mrg /* Check the decimal mode. */
3318 1.1 mrg dtp->u.p.current_unit->decimal_status
3319 1.1 mrg = !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
3320 1.1 mrg find_option (&dtp->common, dtp->decimal, dtp->decimal_len,
3321 1.1 mrg decimal_opt, "Bad DECIMAL parameter in data transfer "
3322 1.1 mrg "statement");
3323 1.1 mrg
3324 1.1 mrg if (dtp->u.p.current_unit->decimal_status == DECIMAL_UNSPECIFIED)
3325 1.1 mrg dtp->u.p.current_unit->decimal_status = dtp->u.p.current_unit->flags.decimal;
3326 1.1 mrg
3327 1.1 mrg /* Check the round mode. */
3328 1.1 mrg dtp->u.p.current_unit->round_status
3329 1.1 mrg = !(cf & IOPARM_DT_HAS_ROUND) ? ROUND_UNSPECIFIED :
3330 1.1 mrg find_option (&dtp->common, dtp->round, dtp->round_len,
3331 1.1 mrg round_opt, "Bad ROUND parameter in data transfer "
3332 1.1 mrg "statement");
3333 1.1 mrg
3334 1.1 mrg if (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED)
3335 1.1 mrg dtp->u.p.current_unit->round_status = dtp->u.p.current_unit->flags.round;
3336 1.1 mrg
3337 1.1 mrg /* Check the sign mode. */
3338 1.1 mrg dtp->u.p.sign_status
3339 1.1 mrg = !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
3340 1.1 mrg find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt,
3341 1.1 mrg "Bad SIGN parameter in data transfer statement");
3342 1.1 mrg
3343 1.1 mrg if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
3344 1.1 mrg dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;
3345 1.1 mrg
3346 1.1 mrg /* Check the blank mode. */
3347 1.1 mrg dtp->u.p.blank_status
3348 1.1 mrg = !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
3349 1.1 mrg find_option (&dtp->common, dtp->blank, dtp->blank_len,
3350 1.1 mrg blank_opt,
3351 1.1 mrg "Bad BLANK parameter in data transfer statement");
3352 1.1 mrg
3353 1.1 mrg if (dtp->u.p.blank_status == BLANK_UNSPECIFIED)
3354 1.1 mrg dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;
3355 1.1 mrg
3356 1.1 mrg /* Check the delim mode. */
3357 1.1 mrg dtp->u.p.current_unit->delim_status
3358 1.1 mrg = !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
3359 1.1 mrg find_option (&dtp->common, dtp->delim, dtp->delim_len,
3360 1.1 mrg delim_opt, "Bad DELIM parameter in data transfer statement");
3361 1.1 mrg
3362 1.1 mrg if (dtp->u.p.current_unit->delim_status == DELIM_UNSPECIFIED)
3363 1.1 mrg {
3364 1.1 mrg if (ionml && dtp->u.p.current_unit->flags.delim == DELIM_UNSPECIFIED)
3365 1.1 mrg dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
3366 1.1 mrg else
3367 1.1 mrg dtp->u.p.current_unit->delim_status = dtp->u.p.current_unit->flags.delim;
3368 1.1 mrg }
3369 1.1 mrg
3370 1.1 mrg /* Check the pad mode. */
3371 1.1 mrg dtp->u.p.current_unit->pad_status
3372 1.1 mrg = !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
3373 1.1 mrg find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt,
3374 1.1 mrg "Bad PAD parameter in data transfer statement");
3375 1.1 mrg
3376 1.1 mrg if (dtp->u.p.current_unit->pad_status == PAD_UNSPECIFIED)
3377 1.1 mrg dtp->u.p.current_unit->pad_status = dtp->u.p.current_unit->flags.pad;
3378 1.1 mrg
3379 1.1 mrg /* Set up the subroutine that will handle the transfers. */
3380 1.1 mrg
3381 1.1 mrg if (read_flag)
3382 1.1 mrg {
3383 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
3384 1.1 mrg dtp->u.p.transfer = unformatted_read;
3385 1.1 mrg else
3386 1.1 mrg {
3387 1.1 mrg if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
3388 1.1 mrg dtp->u.p.transfer = list_formatted_read;
3389 1.1 mrg else
3390 1.1 mrg dtp->u.p.transfer = formatted_transfer;
3391 1.1 mrg }
3392 1.1 mrg }
3393 1.1 mrg else
3394 1.1 mrg {
3395 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
3396 1.1 mrg dtp->u.p.transfer = unformatted_write;
3397 1.1 mrg else
3398 1.1 mrg {
3399 1.1 mrg if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
3400 1.1 mrg dtp->u.p.transfer = list_formatted_write;
3401 1.1 mrg else
3402 1.1 mrg dtp->u.p.transfer = formatted_transfer;
3403 1.1 mrg }
3404 1.1 mrg }
3405 1.1 mrg
3406 1.1 mrg if (au && dtp->u.p.async)
3407 1.1 mrg {
3408 1.1 mrg NOTE ("enqueue_data_transfer");
3409 1.1 mrg enqueue_data_transfer_init (au, dtp, read_flag);
3410 1.1 mrg }
3411 1.1 mrg else
3412 1.1 mrg {
3413 1.1 mrg NOTE ("invoking data_transfer_init_worker");
3414 1.1 mrg data_transfer_init_worker (dtp, read_flag);
3415 1.1 mrg }
3416 1.1 mrg }
3417 1.1 mrg
3418 1.1 mrg void
3419 1.1 mrg data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
3420 1.1 mrg {
3421 1.1 mrg GFC_INTEGER_4 cf = dtp->common.flags;
3422 1.1 mrg
3423 1.1 mrg NOTE ("starting worker...");
3424 1.1 mrg
3425 1.1 mrg if (read_flag && dtp->u.p.current_unit->flags.form != FORM_UNFORMATTED
3426 1.1 mrg && ((cf & IOPARM_DT_LIST_FORMAT) != 0)
3427 1.1 mrg && dtp->u.p.current_unit->child_dtio == 0)
3428 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
3429 1.1 mrg
3430 1.1 mrg /* Check to see if we might be reading what we wrote before */
3431 1.1 mrg
3432 1.1 mrg if (dtp->u.p.mode != dtp->u.p.current_unit->mode
3433 1.1 mrg && !is_internal_unit (dtp))
3434 1.1 mrg {
3435 1.1 mrg int pos = fbuf_reset (dtp->u.p.current_unit);
3436 1.1 mrg if (pos != 0)
3437 1.1 mrg sseek (dtp->u.p.current_unit->s, pos, SEEK_CUR);
3438 1.1 mrg sflush(dtp->u.p.current_unit->s);
3439 1.1 mrg }
3440 1.1 mrg
3441 1.1 mrg /* Check the POS= specifier: that it is in range and that it is used with a
3442 1.1 mrg unit that has been connected for STREAM access. F2003 9.5.1.10. */
3443 1.1 mrg
3444 1.1 mrg if (((cf & IOPARM_DT_HAS_POS) != 0))
3445 1.1 mrg {
3446 1.1 mrg if (is_stream_io (dtp))
3447 1.1 mrg {
3448 1.1 mrg
3449 1.1 mrg if (dtp->pos <= 0)
3450 1.1 mrg {
3451 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3452 1.1 mrg "POS=specifier must be positive");
3453 1.1 mrg return;
3454 1.1 mrg }
3455 1.1 mrg
3456 1.1 mrg if (dtp->pos >= dtp->u.p.current_unit->maxrec)
3457 1.1 mrg {
3458 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3459 1.1 mrg "POS=specifier too large");
3460 1.1 mrg return;
3461 1.1 mrg }
3462 1.1 mrg
3463 1.1 mrg dtp->rec = dtp->pos;
3464 1.1 mrg
3465 1.1 mrg if (dtp->u.p.mode == READING)
3466 1.1 mrg {
3467 1.1 mrg /* Reset the endfile flag; if we hit EOF during reading
3468 1.1 mrg we'll set the flag and generate an error at that point
3469 1.1 mrg rather than worrying about it here. */
3470 1.1 mrg dtp->u.p.current_unit->endfile = NO_ENDFILE;
3471 1.1 mrg }
3472 1.1 mrg
3473 1.1 mrg if (dtp->pos != dtp->u.p.current_unit->strm_pos)
3474 1.1 mrg {
3475 1.1.1.2 mrg fbuf_reset (dtp->u.p.current_unit);
3476 1.1.1.2 mrg if (sseek (dtp->u.p.current_unit->s, dtp->pos - 1,
3477 1.1.1.2 mrg SEEK_SET) < 0)
3478 1.1 mrg {
3479 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3480 1.1 mrg return;
3481 1.1 mrg }
3482 1.1 mrg dtp->u.p.current_unit->strm_pos = dtp->pos;
3483 1.1 mrg }
3484 1.1 mrg }
3485 1.1 mrg else
3486 1.1 mrg {
3487 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3488 1.1 mrg "POS=specifier not allowed, "
3489 1.1 mrg "Try OPEN with ACCESS='stream'");
3490 1.1 mrg return;
3491 1.1 mrg }
3492 1.1 mrg }
3493 1.1 mrg
3494 1.1 mrg
3495 1.1 mrg /* Sanity checks on the record number. */
3496 1.1 mrg if ((cf & IOPARM_DT_HAS_REC) != 0)
3497 1.1 mrg {
3498 1.1 mrg if (dtp->rec <= 0)
3499 1.1 mrg {
3500 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3501 1.1 mrg "Record number must be positive");
3502 1.1 mrg return;
3503 1.1 mrg }
3504 1.1 mrg
3505 1.1 mrg if (dtp->rec >= dtp->u.p.current_unit->maxrec)
3506 1.1 mrg {
3507 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3508 1.1 mrg "Record number too large");
3509 1.1 mrg return;
3510 1.1 mrg }
3511 1.1 mrg
3512 1.1 mrg /* Make sure format buffer is reset. */
3513 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
3514 1.1 mrg fbuf_reset (dtp->u.p.current_unit);
3515 1.1 mrg
3516 1.1 mrg
3517 1.1 mrg /* Check whether the record exists to be read. Only
3518 1.1 mrg a partial record needs to exist. */
3519 1.1 mrg
3520 1.1 mrg if (dtp->u.p.mode == READING && (dtp->rec - 1)
3521 1.1 mrg * dtp->u.p.current_unit->recl >= ssize (dtp->u.p.current_unit->s))
3522 1.1 mrg {
3523 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3524 1.1 mrg "Non-existing record number");
3525 1.1 mrg return;
3526 1.1 mrg }
3527 1.1 mrg
3528 1.1 mrg /* Position the file. */
3529 1.1 mrg if (sseek (dtp->u.p.current_unit->s, (gfc_offset) (dtp->rec - 1)
3530 1.1 mrg * dtp->u.p.current_unit->recl, SEEK_SET) < 0)
3531 1.1 mrg {
3532 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3533 1.1 mrg return;
3534 1.1 mrg }
3535 1.1 mrg
3536 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
3537 1.1 mrg {
3538 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3539 1.1 mrg "Record number not allowed for stream access "
3540 1.1 mrg "data transfer");
3541 1.1 mrg return;
3542 1.1 mrg }
3543 1.1 mrg }
3544 1.1 mrg
3545 1.1 mrg /* Bugware for badly written mixed C-Fortran I/O. */
3546 1.1 mrg if (!is_internal_unit (dtp))
3547 1.1 mrg flush_if_preconnected(dtp->u.p.current_unit->s);
3548 1.1 mrg
3549 1.1 mrg dtp->u.p.current_unit->mode = dtp->u.p.mode;
3550 1.1 mrg
3551 1.1 mrg /* Set the maximum position reached from the previous I/O operation. This
3552 1.1 mrg could be greater than zero from a previous non-advancing write. */
3553 1.1 mrg dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
3554 1.1 mrg
3555 1.1 mrg pre_position (dtp);
3556 1.1 mrg
3557 1.1 mrg /* Make sure that we don't do a read after a nonadvancing write. */
3558 1.1 mrg
3559 1.1 mrg if (read_flag)
3560 1.1 mrg {
3561 1.1 mrg if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
3562 1.1 mrg {
3563 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3564 1.1 mrg "Cannot READ after a nonadvancing WRITE");
3565 1.1 mrg return;
3566 1.1 mrg }
3567 1.1 mrg }
3568 1.1 mrg else
3569 1.1 mrg {
3570 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
3571 1.1 mrg dtp->u.p.current_unit->read_bad = 1;
3572 1.1 mrg }
3573 1.1 mrg
3574 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
3575 1.1 mrg {
3576 1.1.1.3 mrg #ifdef HAVE_POSIX_2008_LOCALE
3577 1.1 mrg dtp->u.p.old_locale = uselocale (c_locale);
3578 1.1 mrg #else
3579 1.1 mrg __gthread_mutex_lock (&old_locale_lock);
3580 1.1 mrg if (!old_locale_ctr++)
3581 1.1 mrg {
3582 1.1 mrg old_locale = setlocale (LC_NUMERIC, NULL);
3583 1.1 mrg setlocale (LC_NUMERIC, "C");
3584 1.1 mrg }
3585 1.1 mrg __gthread_mutex_unlock (&old_locale_lock);
3586 1.1 mrg #endif
3587 1.1 mrg /* Start the data transfer if we are doing a formatted transfer. */
3588 1.1 mrg if ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0
3589 1.1 mrg && dtp->u.p.ionml == NULL)
3590 1.1 mrg formatted_transfer (dtp, 0, NULL, 0, 0, 1);
3591 1.1 mrg }
3592 1.1 mrg }
3593 1.1 mrg
3594 1.1 mrg
3595 1.1 mrg /* Initialize an array_loop_spec given the array descriptor. The function
3596 1.1 mrg returns the index of the last element of the array, and also returns
3597 1.1 mrg starting record, where the first I/O goes to (necessary in case of
3598 1.1 mrg negative strides). */
3599 1.1 mrg
3600 1.1 mrg gfc_offset
3601 1.1 mrg init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
3602 1.1 mrg gfc_offset *start_record)
3603 1.1 mrg {
3604 1.1 mrg int rank = GFC_DESCRIPTOR_RANK(desc);
3605 1.1 mrg int i;
3606 1.1 mrg gfc_offset index;
3607 1.1 mrg int empty;
3608 1.1 mrg
3609 1.1 mrg empty = 0;
3610 1.1 mrg index = 1;
3611 1.1 mrg *start_record = 0;
3612 1.1 mrg
3613 1.1 mrg for (i=0; i<rank; i++)
3614 1.1 mrg {
3615 1.1 mrg ls[i].idx = GFC_DESCRIPTOR_LBOUND(desc,i);
3616 1.1 mrg ls[i].start = GFC_DESCRIPTOR_LBOUND(desc,i);
3617 1.1 mrg ls[i].end = GFC_DESCRIPTOR_UBOUND(desc,i);
3618 1.1 mrg ls[i].step = GFC_DESCRIPTOR_STRIDE(desc,i);
3619 1.1 mrg empty = empty || (GFC_DESCRIPTOR_UBOUND(desc,i)
3620 1.1 mrg < GFC_DESCRIPTOR_LBOUND(desc,i));
3621 1.1 mrg
3622 1.1 mrg if (GFC_DESCRIPTOR_STRIDE(desc,i) > 0)
3623 1.1 mrg {
3624 1.1 mrg index += (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
3625 1.1 mrg * GFC_DESCRIPTOR_STRIDE(desc,i);
3626 1.1 mrg }
3627 1.1 mrg else
3628 1.1 mrg {
3629 1.1 mrg index -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
3630 1.1 mrg * GFC_DESCRIPTOR_STRIDE(desc,i);
3631 1.1 mrg *start_record -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
3632 1.1 mrg * GFC_DESCRIPTOR_STRIDE(desc,i);
3633 1.1 mrg }
3634 1.1 mrg }
3635 1.1 mrg
3636 1.1 mrg if (empty)
3637 1.1 mrg return 0;
3638 1.1 mrg else
3639 1.1 mrg return index;
3640 1.1 mrg }
3641 1.1 mrg
3642 1.1 mrg /* Determine the index to the next record in an internal unit array by
3643 1.1 mrg by incrementing through the array_loop_spec. */
3644 1.1 mrg
3645 1.1 mrg gfc_offset
3646 1.1 mrg next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
3647 1.1 mrg {
3648 1.1 mrg int i, carry;
3649 1.1 mrg gfc_offset index;
3650 1.1 mrg
3651 1.1 mrg carry = 1;
3652 1.1 mrg index = 0;
3653 1.1 mrg
3654 1.1 mrg for (i = 0; i < dtp->u.p.current_unit->rank; i++)
3655 1.1 mrg {
3656 1.1 mrg if (carry)
3657 1.1 mrg {
3658 1.1 mrg ls[i].idx++;
3659 1.1 mrg if (ls[i].idx > ls[i].end)
3660 1.1 mrg {
3661 1.1 mrg ls[i].idx = ls[i].start;
3662 1.1 mrg carry = 1;
3663 1.1 mrg }
3664 1.1 mrg else
3665 1.1 mrg carry = 0;
3666 1.1 mrg }
3667 1.1 mrg index = index + (ls[i].idx - ls[i].start) * ls[i].step;
3668 1.1 mrg }
3669 1.1 mrg
3670 1.1 mrg *finished = carry;
3671 1.1 mrg
3672 1.1 mrg return index;
3673 1.1 mrg }
3674 1.1 mrg
3675 1.1 mrg
3676 1.1 mrg
3677 1.1 mrg /* Skip to the end of the current record, taking care of an optional
3678 1.1 mrg record marker of size bytes. If the file is not seekable, we
3679 1.1 mrg read chunks of size MAX_READ until we get to the right
3680 1.1 mrg position. */
3681 1.1 mrg
3682 1.1 mrg static void
3683 1.1 mrg skip_record (st_parameter_dt *dtp, gfc_offset bytes)
3684 1.1 mrg {
3685 1.1 mrg ssize_t rlength, readb;
3686 1.1 mrg #define MAX_READ 4096
3687 1.1 mrg char p[MAX_READ];
3688 1.1 mrg
3689 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord += bytes;
3690 1.1 mrg if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
3691 1.1 mrg return;
3692 1.1 mrg
3693 1.1 mrg /* Direct access files do not generate END conditions,
3694 1.1 mrg only I/O errors. */
3695 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
3696 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
3697 1.1 mrg {
3698 1.1 mrg /* Seeking failed, fall back to seeking by reading data. */
3699 1.1 mrg while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
3700 1.1 mrg {
3701 1.1 mrg rlength =
3702 1.1 mrg (MAX_READ < dtp->u.p.current_unit->bytes_left_subrecord) ?
3703 1.1 mrg MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
3704 1.1 mrg
3705 1.1 mrg readb = sread (dtp->u.p.current_unit->s, p, rlength);
3706 1.1 mrg if (readb < 0)
3707 1.1 mrg {
3708 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3709 1.1 mrg return;
3710 1.1 mrg }
3711 1.1 mrg
3712 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord -= readb;
3713 1.1 mrg }
3714 1.1 mrg return;
3715 1.1 mrg }
3716 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord = 0;
3717 1.1 mrg }
3718 1.1 mrg
3719 1.1 mrg
3720 1.1 mrg /* Advance to the next record reading unformatted files, taking
3721 1.1 mrg care of subrecords. If complete_record is nonzero, we loop
3722 1.1 mrg until all subrecords are cleared. */
3723 1.1 mrg
3724 1.1 mrg static void
3725 1.1 mrg next_record_r_unf (st_parameter_dt *dtp, int complete_record)
3726 1.1 mrg {
3727 1.1 mrg size_t bytes;
3728 1.1 mrg
3729 1.1 mrg bytes = compile_options.record_marker == 0 ?
3730 1.1 mrg sizeof (GFC_INTEGER_4) : compile_options.record_marker;
3731 1.1 mrg
3732 1.1 mrg while(1)
3733 1.1 mrg {
3734 1.1 mrg
3735 1.1 mrg /* Skip over tail */
3736 1.1 mrg
3737 1.1 mrg skip_record (dtp, bytes);
3738 1.1 mrg
3739 1.1 mrg if ( ! (complete_record && dtp->u.p.current_unit->continued))
3740 1.1 mrg return;
3741 1.1 mrg
3742 1.1 mrg us_read (dtp, 1);
3743 1.1 mrg }
3744 1.1 mrg }
3745 1.1 mrg
3746 1.1 mrg
3747 1.1 mrg static gfc_offset
3748 1.1 mrg min_off (gfc_offset a, gfc_offset b)
3749 1.1 mrg {
3750 1.1 mrg return (a < b ? a : b);
3751 1.1 mrg }
3752 1.1 mrg
3753 1.1 mrg
3754 1.1 mrg /* Space to the next record for read mode. */
3755 1.1 mrg
3756 1.1 mrg static void
3757 1.1 mrg next_record_r (st_parameter_dt *dtp, int done)
3758 1.1 mrg {
3759 1.1 mrg gfc_offset record;
3760 1.1 mrg char p;
3761 1.1 mrg int cc;
3762 1.1 mrg
3763 1.1 mrg switch (current_mode (dtp))
3764 1.1 mrg {
3765 1.1 mrg /* No records in unformatted STREAM I/O. */
3766 1.1 mrg case UNFORMATTED_STREAM:
3767 1.1 mrg return;
3768 1.1 mrg
3769 1.1 mrg case UNFORMATTED_SEQUENTIAL:
3770 1.1 mrg next_record_r_unf (dtp, 1);
3771 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
3772 1.1 mrg break;
3773 1.1 mrg
3774 1.1 mrg case FORMATTED_DIRECT:
3775 1.1 mrg case UNFORMATTED_DIRECT:
3776 1.1 mrg skip_record (dtp, dtp->u.p.current_unit->bytes_left);
3777 1.1 mrg break;
3778 1.1 mrg
3779 1.1 mrg case FORMATTED_STREAM:
3780 1.1 mrg case FORMATTED_SEQUENTIAL:
3781 1.1 mrg /* read_sf has already terminated input because of an '\n', or
3782 1.1 mrg we have hit EOF. */
3783 1.1 mrg if (dtp->u.p.sf_seen_eor)
3784 1.1 mrg {
3785 1.1 mrg dtp->u.p.sf_seen_eor = 0;
3786 1.1 mrg break;
3787 1.1 mrg }
3788 1.1 mrg
3789 1.1 mrg if (is_internal_unit (dtp))
3790 1.1 mrg {
3791 1.1 mrg if (is_array_io (dtp))
3792 1.1 mrg {
3793 1.1 mrg int finished;
3794 1.1 mrg
3795 1.1 mrg record = next_array_record (dtp, dtp->u.p.current_unit->ls,
3796 1.1 mrg &finished);
3797 1.1 mrg if (!done && finished)
3798 1.1 mrg hit_eof (dtp);
3799 1.1 mrg
3800 1.1 mrg /* Now seek to this record. */
3801 1.1 mrg record = record * dtp->u.p.current_unit->recl;
3802 1.1 mrg if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
3803 1.1 mrg {
3804 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3805 1.1 mrg break;
3806 1.1 mrg }
3807 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
3808 1.1 mrg }
3809 1.1 mrg else
3810 1.1 mrg {
3811 1.1 mrg gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
3812 1.1 mrg bytes_left = min_off (bytes_left,
3813 1.1 mrg ssize (dtp->u.p.current_unit->s)
3814 1.1 mrg - stell (dtp->u.p.current_unit->s));
3815 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
3816 1.1 mrg bytes_left, SEEK_CUR) < 0)
3817 1.1 mrg {
3818 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3819 1.1 mrg break;
3820 1.1 mrg }
3821 1.1 mrg dtp->u.p.current_unit->bytes_left
3822 1.1 mrg = dtp->u.p.current_unit->recl;
3823 1.1 mrg }
3824 1.1 mrg break;
3825 1.1 mrg }
3826 1.1 mrg else if (dtp->u.p.current_unit->flags.cc != CC_NONE)
3827 1.1 mrg {
3828 1.1 mrg do
3829 1.1 mrg {
3830 1.1 mrg errno = 0;
3831 1.1 mrg cc = fbuf_getc (dtp->u.p.current_unit);
3832 1.1 mrg if (cc == EOF)
3833 1.1 mrg {
3834 1.1 mrg if (errno != 0)
3835 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3836 1.1 mrg else
3837 1.1 mrg {
3838 1.1 mrg if (is_stream_io (dtp)
3839 1.1 mrg || dtp->u.p.current_unit->pad_status == PAD_NO
3840 1.1 mrg || dtp->u.p.current_unit->bytes_left
3841 1.1 mrg == dtp->u.p.current_unit->recl)
3842 1.1 mrg hit_eof (dtp);
3843 1.1 mrg }
3844 1.1 mrg break;
3845 1.1 mrg }
3846 1.1 mrg
3847 1.1 mrg if (is_stream_io (dtp))
3848 1.1 mrg dtp->u.p.current_unit->strm_pos++;
3849 1.1 mrg
3850 1.1 mrg p = (char) cc;
3851 1.1 mrg }
3852 1.1 mrg while (p != '\n');
3853 1.1 mrg }
3854 1.1 mrg break;
3855 1.1.1.2 mrg case FORMATTED_UNSPECIFIED:
3856 1.1.1.2 mrg gcc_unreachable ();
3857 1.1 mrg }
3858 1.1 mrg }
3859 1.1 mrg
3860 1.1 mrg
3861 1.1 mrg /* Small utility function to write a record marker, taking care of
3862 1.1 mrg byte swapping and of choosing the correct size. */
3863 1.1 mrg
3864 1.1 mrg static int
3865 1.1 mrg write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
3866 1.1 mrg {
3867 1.1 mrg size_t len;
3868 1.1 mrg GFC_INTEGER_4 buf4;
3869 1.1 mrg GFC_INTEGER_8 buf8;
3870 1.1 mrg
3871 1.1 mrg if (compile_options.record_marker == 0)
3872 1.1 mrg len = sizeof (GFC_INTEGER_4);
3873 1.1 mrg else
3874 1.1 mrg len = compile_options.record_marker;
3875 1.1 mrg
3876 1.1.1.3 mrg int convert = dtp->u.p.current_unit->flags.convert;
3877 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
3878 1.1.1.3 mrg convert &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
3879 1.1.1.3 mrg #endif
3880 1.1 mrg /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
3881 1.1.1.3 mrg if (likely (convert == GFC_CONVERT_NATIVE))
3882 1.1 mrg {
3883 1.1 mrg switch (len)
3884 1.1 mrg {
3885 1.1 mrg case sizeof (GFC_INTEGER_4):
3886 1.1 mrg buf4 = buf;
3887 1.1 mrg return swrite (dtp->u.p.current_unit->s, &buf4, len);
3888 1.1 mrg break;
3889 1.1 mrg
3890 1.1 mrg case sizeof (GFC_INTEGER_8):
3891 1.1 mrg buf8 = buf;
3892 1.1 mrg return swrite (dtp->u.p.current_unit->s, &buf8, len);
3893 1.1 mrg break;
3894 1.1 mrg
3895 1.1 mrg default:
3896 1.1 mrg runtime_error ("Illegal value for record marker");
3897 1.1 mrg break;
3898 1.1 mrg }
3899 1.1 mrg }
3900 1.1 mrg else
3901 1.1 mrg {
3902 1.1 mrg uint32_t u32;
3903 1.1 mrg uint64_t u64;
3904 1.1 mrg switch (len)
3905 1.1 mrg {
3906 1.1 mrg case sizeof (GFC_INTEGER_4):
3907 1.1 mrg buf4 = buf;
3908 1.1 mrg memcpy (&u32, &buf4, sizeof (u32));
3909 1.1 mrg u32 = __builtin_bswap32 (u32);
3910 1.1 mrg return swrite (dtp->u.p.current_unit->s, &u32, len);
3911 1.1 mrg break;
3912 1.1 mrg
3913 1.1 mrg case sizeof (GFC_INTEGER_8):
3914 1.1 mrg buf8 = buf;
3915 1.1 mrg memcpy (&u64, &buf8, sizeof (u64));
3916 1.1 mrg u64 = __builtin_bswap64 (u64);
3917 1.1 mrg return swrite (dtp->u.p.current_unit->s, &u64, len);
3918 1.1 mrg break;
3919 1.1 mrg
3920 1.1 mrg default:
3921 1.1 mrg runtime_error ("Illegal value for record marker");
3922 1.1 mrg break;
3923 1.1 mrg }
3924 1.1 mrg }
3925 1.1 mrg
3926 1.1 mrg }
3927 1.1 mrg
3928 1.1 mrg /* Position to the next (sub)record in write mode for
3929 1.1 mrg unformatted sequential files. */
3930 1.1 mrg
3931 1.1 mrg static void
3932 1.1 mrg next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
3933 1.1 mrg {
3934 1.1 mrg gfc_offset m, m_write, record_marker;
3935 1.1 mrg
3936 1.1 mrg /* Bytes written. */
3937 1.1 mrg m = dtp->u.p.current_unit->recl_subrecord
3938 1.1 mrg - dtp->u.p.current_unit->bytes_left_subrecord;
3939 1.1 mrg
3940 1.1 mrg if (compile_options.record_marker == 0)
3941 1.1 mrg record_marker = sizeof (GFC_INTEGER_4);
3942 1.1 mrg else
3943 1.1 mrg record_marker = compile_options.record_marker;
3944 1.1 mrg
3945 1.1 mrg /* Seek to the head and overwrite the bogus length with the real
3946 1.1 mrg length. */
3947 1.1 mrg
3948 1.1 mrg if (unlikely (sseek (dtp->u.p.current_unit->s, - m - record_marker,
3949 1.1 mrg SEEK_CUR) < 0))
3950 1.1 mrg goto io_error;
3951 1.1 mrg
3952 1.1 mrg if (next_subrecord)
3953 1.1 mrg m_write = -m;
3954 1.1 mrg else
3955 1.1 mrg m_write = m;
3956 1.1 mrg
3957 1.1 mrg if (unlikely (write_us_marker (dtp, m_write) < 0))
3958 1.1 mrg goto io_error;
3959 1.1 mrg
3960 1.1 mrg /* Seek past the end of the current record. */
3961 1.1 mrg
3962 1.1 mrg if (unlikely (sseek (dtp->u.p.current_unit->s, m, SEEK_CUR) < 0))
3963 1.1 mrg goto io_error;
3964 1.1 mrg
3965 1.1 mrg /* Write the length tail. If we finish a record containing
3966 1.1 mrg subrecords, we write out the negative length. */
3967 1.1 mrg
3968 1.1 mrg if (dtp->u.p.current_unit->continued)
3969 1.1 mrg m_write = -m;
3970 1.1 mrg else
3971 1.1 mrg m_write = m;
3972 1.1 mrg
3973 1.1 mrg if (unlikely (write_us_marker (dtp, m_write) < 0))
3974 1.1 mrg goto io_error;
3975 1.1 mrg
3976 1.1 mrg return;
3977 1.1 mrg
3978 1.1 mrg io_error:
3979 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3980 1.1 mrg return;
3981 1.1 mrg
3982 1.1 mrg }
3983 1.1 mrg
3984 1.1 mrg
3985 1.1 mrg /* Utility function like memset() but operating on streams. Return
3986 1.1 mrg value is same as for POSIX write(). */
3987 1.1 mrg
3988 1.1 mrg static gfc_offset
3989 1.1 mrg sset (stream *s, int c, gfc_offset nbyte)
3990 1.1 mrg {
3991 1.1 mrg #define WRITE_CHUNK 256
3992 1.1 mrg char p[WRITE_CHUNK];
3993 1.1 mrg gfc_offset bytes_left;
3994 1.1 mrg ssize_t trans;
3995 1.1 mrg
3996 1.1 mrg if (nbyte < WRITE_CHUNK)
3997 1.1 mrg memset (p, c, nbyte);
3998 1.1 mrg else
3999 1.1 mrg memset (p, c, WRITE_CHUNK);
4000 1.1 mrg
4001 1.1 mrg bytes_left = nbyte;
4002 1.1 mrg while (bytes_left > 0)
4003 1.1 mrg {
4004 1.1 mrg trans = (bytes_left < WRITE_CHUNK) ? bytes_left : WRITE_CHUNK;
4005 1.1 mrg trans = swrite (s, p, trans);
4006 1.1 mrg if (trans <= 0)
4007 1.1 mrg return trans;
4008 1.1 mrg bytes_left -= trans;
4009 1.1 mrg }
4010 1.1 mrg
4011 1.1 mrg return nbyte - bytes_left;
4012 1.1 mrg }
4013 1.1 mrg
4014 1.1 mrg
4015 1.1 mrg /* Finish up a record according to the legacy carriagecontrol type, based
4016 1.1 mrg on the first character in the record. */
4017 1.1 mrg
4018 1.1 mrg static void
4019 1.1 mrg next_record_cc (st_parameter_dt *dtp)
4020 1.1 mrg {
4021 1.1 mrg /* Only valid with CARRIAGECONTROL=FORTRAN. */
4022 1.1 mrg if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
4023 1.1 mrg return;
4024 1.1 mrg
4025 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
4026 1.1 mrg if (dtp->u.p.cc.len > 0)
4027 1.1 mrg {
4028 1.1 mrg char *p = fbuf_alloc (dtp->u.p.current_unit, dtp->u.p.cc.len);
4029 1.1 mrg if (!p)
4030 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
4031 1.1 mrg
4032 1.1 mrg /* Output CR for the first character with default CC setting. */
4033 1.1 mrg *(p++) = dtp->u.p.cc.u.end;
4034 1.1 mrg if (dtp->u.p.cc.len > 1)
4035 1.1 mrg *p = dtp->u.p.cc.u.end;
4036 1.1 mrg }
4037 1.1 mrg }
4038 1.1 mrg
4039 1.1 mrg /* Position to the next record in write mode. */
4040 1.1 mrg
4041 1.1 mrg static void
4042 1.1 mrg next_record_w (st_parameter_dt *dtp, int done)
4043 1.1 mrg {
4044 1.1 mrg gfc_offset max_pos_off;
4045 1.1 mrg
4046 1.1 mrg /* Zero counters for X- and T-editing. */
4047 1.1 mrg max_pos_off = dtp->u.p.max_pos;
4048 1.1 mrg dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
4049 1.1 mrg
4050 1.1 mrg switch (current_mode (dtp))
4051 1.1 mrg {
4052 1.1 mrg /* No records in unformatted STREAM I/O. */
4053 1.1 mrg case UNFORMATTED_STREAM:
4054 1.1 mrg return;
4055 1.1 mrg
4056 1.1 mrg case FORMATTED_DIRECT:
4057 1.1 mrg if (dtp->u.p.current_unit->bytes_left == 0)
4058 1.1 mrg break;
4059 1.1 mrg
4060 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
4061 1.1 mrg fbuf_flush (dtp->u.p.current_unit, WRITING);
4062 1.1 mrg if (sset (dtp->u.p.current_unit->s, ' ',
4063 1.1 mrg dtp->u.p.current_unit->bytes_left)
4064 1.1 mrg != dtp->u.p.current_unit->bytes_left)
4065 1.1 mrg goto io_error;
4066 1.1 mrg
4067 1.1 mrg break;
4068 1.1 mrg
4069 1.1 mrg case UNFORMATTED_DIRECT:
4070 1.1 mrg if (dtp->u.p.current_unit->bytes_left > 0)
4071 1.1 mrg {
4072 1.1 mrg gfc_offset length = dtp->u.p.current_unit->bytes_left;
4073 1.1 mrg if (sset (dtp->u.p.current_unit->s, 0, length) != length)
4074 1.1 mrg goto io_error;
4075 1.1 mrg }
4076 1.1 mrg break;
4077 1.1 mrg
4078 1.1 mrg case UNFORMATTED_SEQUENTIAL:
4079 1.1 mrg next_record_w_unf (dtp, 0);
4080 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
4081 1.1 mrg break;
4082 1.1 mrg
4083 1.1 mrg case FORMATTED_STREAM:
4084 1.1 mrg case FORMATTED_SEQUENTIAL:
4085 1.1 mrg
4086 1.1 mrg if (is_internal_unit (dtp))
4087 1.1 mrg {
4088 1.1 mrg char *p;
4089 1.1 mrg /* Internal unit, so must fit in memory. */
4090 1.1 mrg size_t length, m;
4091 1.1 mrg size_t max_pos = max_pos_off;
4092 1.1 mrg if (is_array_io (dtp))
4093 1.1 mrg {
4094 1.1 mrg int finished;
4095 1.1 mrg
4096 1.1 mrg length = dtp->u.p.current_unit->bytes_left;
4097 1.1 mrg
4098 1.1 mrg /* If the farthest position reached is greater than current
4099 1.1 mrg position, adjust the position and set length to pad out
4100 1.1 mrg whats left. Otherwise just pad whats left.
4101 1.1 mrg (for character array unit) */
4102 1.1 mrg m = dtp->u.p.current_unit->recl
4103 1.1 mrg - dtp->u.p.current_unit->bytes_left;
4104 1.1 mrg if (max_pos > m)
4105 1.1 mrg {
4106 1.1 mrg length = (max_pos - m);
4107 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
4108 1.1 mrg length, SEEK_CUR) < 0)
4109 1.1 mrg {
4110 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
4111 1.1 mrg return;
4112 1.1 mrg }
4113 1.1 mrg length = ((size_t) dtp->u.p.current_unit->recl - max_pos);
4114 1.1 mrg }
4115 1.1 mrg
4116 1.1 mrg p = write_block (dtp, length);
4117 1.1 mrg if (p == NULL)
4118 1.1 mrg return;
4119 1.1 mrg
4120 1.1 mrg if (unlikely (is_char4_unit (dtp)))
4121 1.1 mrg {
4122 1.1 mrg gfc_char4_t *p4 = (gfc_char4_t *) p;
4123 1.1 mrg memset4 (p4, ' ', length);
4124 1.1 mrg }
4125 1.1 mrg else
4126 1.1 mrg memset (p, ' ', length);
4127 1.1 mrg
4128 1.1 mrg /* Now that the current record has been padded out,
4129 1.1 mrg determine where the next record in the array is.
4130 1.1 mrg Note that this can return a negative value, so it
4131 1.1 mrg needs to be assigned to a signed value. */
4132 1.1 mrg gfc_offset record = next_array_record
4133 1.1 mrg (dtp, dtp->u.p.current_unit->ls, &finished);
4134 1.1 mrg if (finished)
4135 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4136 1.1 mrg
4137 1.1 mrg /* Now seek to this record */
4138 1.1 mrg record = record * dtp->u.p.current_unit->recl;
4139 1.1 mrg
4140 1.1 mrg if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
4141 1.1 mrg {
4142 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
4143 1.1 mrg return;
4144 1.1 mrg }
4145 1.1 mrg
4146 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
4147 1.1 mrg }
4148 1.1 mrg else
4149 1.1 mrg {
4150 1.1 mrg length = 1;
4151 1.1 mrg
4152 1.1 mrg /* If this is the last call to next_record move to the farthest
4153 1.1 mrg position reached and set length to pad out the remainder
4154 1.1 mrg of the record. (for character scaler unit) */
4155 1.1 mrg if (done)
4156 1.1 mrg {
4157 1.1 mrg m = dtp->u.p.current_unit->recl
4158 1.1 mrg - dtp->u.p.current_unit->bytes_left;
4159 1.1 mrg if (max_pos > m)
4160 1.1 mrg {
4161 1.1 mrg length = max_pos - m;
4162 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
4163 1.1 mrg length, SEEK_CUR) < 0)
4164 1.1 mrg {
4165 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
4166 1.1 mrg return;
4167 1.1 mrg }
4168 1.1 mrg length = (size_t) dtp->u.p.current_unit->recl
4169 1.1 mrg - max_pos;
4170 1.1 mrg }
4171 1.1 mrg else
4172 1.1 mrg length = dtp->u.p.current_unit->bytes_left;
4173 1.1 mrg }
4174 1.1 mrg if (length > 0)
4175 1.1 mrg {
4176 1.1 mrg p = write_block (dtp, length);
4177 1.1 mrg if (p == NULL)
4178 1.1 mrg return;
4179 1.1 mrg
4180 1.1 mrg if (unlikely (is_char4_unit (dtp)))
4181 1.1 mrg {
4182 1.1 mrg gfc_char4_t *p4 = (gfc_char4_t *) p;
4183 1.1 mrg memset4 (p4, (gfc_char4_t) ' ', length);
4184 1.1 mrg }
4185 1.1 mrg else
4186 1.1 mrg memset (p, ' ', length);
4187 1.1 mrg }
4188 1.1 mrg }
4189 1.1 mrg }
4190 1.1.1.3 mrg else if (dtp->u.p.seen_dollar == 1)
4191 1.1.1.3 mrg break;
4192 1.1 mrg /* Handle legacy CARRIAGECONTROL line endings. */
4193 1.1 mrg else if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
4194 1.1 mrg next_record_cc (dtp);
4195 1.1 mrg else
4196 1.1 mrg {
4197 1.1 mrg /* Skip newlines for CC=CC_NONE. */
4198 1.1 mrg const int len = (dtp->u.p.current_unit->flags.cc == CC_NONE)
4199 1.1 mrg ? 0
4200 1.1 mrg #ifdef HAVE_CRLF
4201 1.1 mrg : 2;
4202 1.1 mrg #else
4203 1.1 mrg : 1;
4204 1.1 mrg #endif
4205 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
4206 1.1 mrg if (dtp->u.p.current_unit->flags.cc != CC_NONE)
4207 1.1 mrg {
4208 1.1 mrg char *p = fbuf_alloc (dtp->u.p.current_unit, len);
4209 1.1 mrg if (!p)
4210 1.1 mrg goto io_error;
4211 1.1 mrg #ifdef HAVE_CRLF
4212 1.1 mrg *(p++) = '\r';
4213 1.1 mrg #endif
4214 1.1 mrg *p = '\n';
4215 1.1 mrg }
4216 1.1 mrg if (is_stream_io (dtp))
4217 1.1 mrg {
4218 1.1 mrg dtp->u.p.current_unit->strm_pos += len;
4219 1.1 mrg if (dtp->u.p.current_unit->strm_pos
4220 1.1 mrg < ssize (dtp->u.p.current_unit->s))
4221 1.1 mrg unit_truncate (dtp->u.p.current_unit,
4222 1.1 mrg dtp->u.p.current_unit->strm_pos - 1,
4223 1.1 mrg &dtp->common);
4224 1.1 mrg }
4225 1.1 mrg }
4226 1.1 mrg
4227 1.1 mrg break;
4228 1.1.1.2 mrg case FORMATTED_UNSPECIFIED:
4229 1.1.1.2 mrg gcc_unreachable ();
4230 1.1 mrg
4231 1.1 mrg io_error:
4232 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
4233 1.1 mrg break;
4234 1.1 mrg }
4235 1.1 mrg }
4236 1.1 mrg
4237 1.1 mrg /* Position to the next record, which means moving to the end of the
4238 1.1 mrg current record. This can happen under several different
4239 1.1 mrg conditions. If the done flag is not set, we get ready to process
4240 1.1 mrg the next record. */
4241 1.1 mrg
4242 1.1 mrg void
4243 1.1 mrg next_record (st_parameter_dt *dtp, int done)
4244 1.1 mrg {
4245 1.1 mrg gfc_offset fp; /* File position. */
4246 1.1 mrg
4247 1.1 mrg dtp->u.p.current_unit->read_bad = 0;
4248 1.1 mrg
4249 1.1 mrg if (dtp->u.p.mode == READING)
4250 1.1 mrg next_record_r (dtp, done);
4251 1.1 mrg else
4252 1.1 mrg next_record_w (dtp, done);
4253 1.1 mrg
4254 1.1 mrg fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
4255 1.1 mrg
4256 1.1 mrg if (!is_stream_io (dtp))
4257 1.1 mrg {
4258 1.1 mrg /* Since we have changed the position, set it to unspecified so
4259 1.1 mrg that INQUIRE(POSITION=) knows it needs to look into it. */
4260 1.1 mrg if (done)
4261 1.1 mrg dtp->u.p.current_unit->flags.position = POSITION_UNSPECIFIED;
4262 1.1 mrg
4263 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4264 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
4265 1.1 mrg {
4266 1.1 mrg fp = stell (dtp->u.p.current_unit->s);
4267 1.1 mrg /* Calculate next record, rounding up partial records. */
4268 1.1 mrg dtp->u.p.current_unit->last_record =
4269 1.1 mrg (fp + dtp->u.p.current_unit->recl) /
4270 1.1 mrg dtp->u.p.current_unit->recl - 1;
4271 1.1 mrg }
4272 1.1 mrg else
4273 1.1 mrg dtp->u.p.current_unit->last_record++;
4274 1.1 mrg }
4275 1.1 mrg
4276 1.1 mrg if (!done)
4277 1.1 mrg pre_position (dtp);
4278 1.1 mrg
4279 1.1 mrg smarkeor (dtp->u.p.current_unit->s);
4280 1.1 mrg }
4281 1.1 mrg
4282 1.1 mrg
4283 1.1 mrg /* Finalize the current data transfer. For a nonadvancing transfer,
4284 1.1 mrg this means advancing to the next record. For internal units close the
4285 1.1 mrg stream associated with the unit. */
4286 1.1 mrg
4287 1.1 mrg static void
4288 1.1 mrg finalize_transfer (st_parameter_dt *dtp)
4289 1.1 mrg {
4290 1.1 mrg GFC_INTEGER_4 cf = dtp->common.flags;
4291 1.1 mrg
4292 1.1 mrg if ((dtp->u.p.ionml != NULL)
4293 1.1 mrg && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
4294 1.1 mrg {
4295 1.1.1.3 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
4296 1.1.1.3 mrg {
4297 1.1.1.3 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
4298 1.1.1.3 mrg "Namelist formatting for unit connected "
4299 1.1.1.3 mrg "with FORM='UNFORMATTED'");
4300 1.1.1.3 mrg return;
4301 1.1.1.3 mrg }
4302 1.1.1.3 mrg
4303 1.1 mrg dtp->u.p.namelist_mode = 1;
4304 1.1 mrg if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
4305 1.1 mrg namelist_read (dtp);
4306 1.1 mrg else
4307 1.1 mrg namelist_write (dtp);
4308 1.1 mrg }
4309 1.1 mrg
4310 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
4311 1.1 mrg *dtp->size = dtp->u.p.current_unit->size_used;
4312 1.1 mrg
4313 1.1 mrg if (dtp->u.p.eor_condition)
4314 1.1 mrg {
4315 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
4316 1.1 mrg goto done;
4317 1.1 mrg }
4318 1.1 mrg
4319 1.1 mrg if (dtp->u.p.current_unit && (dtp->u.p.current_unit->child_dtio > 0))
4320 1.1 mrg {
4321 1.1 mrg if (cf & IOPARM_DT_HAS_FORMAT)
4322 1.1 mrg {
4323 1.1 mrg free (dtp->u.p.fmt);
4324 1.1 mrg free (dtp->format);
4325 1.1 mrg }
4326 1.1 mrg return;
4327 1.1 mrg }
4328 1.1 mrg
4329 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
4330 1.1 mrg {
4331 1.1 mrg if (dtp->u.p.current_unit && current_mode (dtp) == UNFORMATTED_SEQUENTIAL)
4332 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4333 1.1 mrg goto done;
4334 1.1 mrg }
4335 1.1 mrg
4336 1.1 mrg dtp->u.p.transfer = NULL;
4337 1.1 mrg if (dtp->u.p.current_unit == NULL)
4338 1.1 mrg goto done;
4339 1.1 mrg
4340 1.1 mrg if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
4341 1.1 mrg {
4342 1.1 mrg finish_list_read (dtp);
4343 1.1 mrg goto done;
4344 1.1 mrg }
4345 1.1 mrg
4346 1.1 mrg if (dtp->u.p.mode == WRITING)
4347 1.1 mrg dtp->u.p.current_unit->previous_nonadvancing_write
4348 1.1 mrg = dtp->u.p.advance_status == ADVANCE_NO;
4349 1.1 mrg
4350 1.1 mrg if (is_stream_io (dtp))
4351 1.1 mrg {
4352 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
4353 1.1 mrg && dtp->u.p.advance_status != ADVANCE_NO)
4354 1.1 mrg next_record (dtp, 1);
4355 1.1 mrg
4356 1.1 mrg goto done;
4357 1.1 mrg }
4358 1.1 mrg
4359 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4360 1.1 mrg
4361 1.1 mrg if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
4362 1.1 mrg {
4363 1.1 mrg fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
4364 1.1 mrg dtp->u.p.seen_dollar = 0;
4365 1.1 mrg goto done;
4366 1.1 mrg }
4367 1.1 mrg
4368 1.1 mrg /* For non-advancing I/O, save the current maximum position for use in the
4369 1.1 mrg next I/O operation if needed. */
4370 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO)
4371 1.1 mrg {
4372 1.1 mrg if (dtp->u.p.skips > 0)
4373 1.1 mrg {
4374 1.1 mrg int tmp;
4375 1.1 mrg write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
4376 1.1 mrg tmp = (int)(dtp->u.p.current_unit->recl
4377 1.1 mrg - dtp->u.p.current_unit->bytes_left);
4378 1.1 mrg dtp->u.p.max_pos =
4379 1.1 mrg dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
4380 1.1 mrg dtp->u.p.skips = 0;
4381 1.1 mrg }
4382 1.1 mrg int bytes_written = (int) (dtp->u.p.current_unit->recl
4383 1.1 mrg - dtp->u.p.current_unit->bytes_left);
4384 1.1 mrg dtp->u.p.current_unit->saved_pos =
4385 1.1 mrg dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
4386 1.1 mrg fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
4387 1.1 mrg goto done;
4388 1.1 mrg }
4389 1.1 mrg else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
4390 1.1 mrg && dtp->u.p.mode == WRITING && !is_internal_unit (dtp))
4391 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
4392 1.1 mrg
4393 1.1 mrg dtp->u.p.current_unit->saved_pos = 0;
4394 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
4395 1.1 mrg next_record (dtp, 1);
4396 1.1 mrg
4397 1.1 mrg done:
4398 1.1 mrg
4399 1.1 mrg if (dtp->u.p.unit_is_internal)
4400 1.1 mrg {
4401 1.1 mrg /* The unit structure may be reused later so clear the
4402 1.1 mrg internal unit kind. */
4403 1.1 mrg dtp->u.p.current_unit->internal_unit_kind = 0;
4404 1.1 mrg
4405 1.1 mrg fbuf_destroy (dtp->u.p.current_unit);
4406 1.1 mrg if (dtp->u.p.current_unit
4407 1.1 mrg && (dtp->u.p.current_unit->child_dtio == 0)
4408 1.1 mrg && dtp->u.p.current_unit->s)
4409 1.1 mrg {
4410 1.1 mrg sclose (dtp->u.p.current_unit->s);
4411 1.1 mrg dtp->u.p.current_unit->s = NULL;
4412 1.1 mrg }
4413 1.1 mrg }
4414 1.1 mrg
4415 1.1.1.3 mrg #ifdef HAVE_POSIX_2008_LOCALE
4416 1.1 mrg if (dtp->u.p.old_locale != (locale_t) 0)
4417 1.1 mrg {
4418 1.1 mrg uselocale (dtp->u.p.old_locale);
4419 1.1 mrg dtp->u.p.old_locale = (locale_t) 0;
4420 1.1 mrg }
4421 1.1 mrg #else
4422 1.1 mrg __gthread_mutex_lock (&old_locale_lock);
4423 1.1 mrg if (!--old_locale_ctr)
4424 1.1 mrg {
4425 1.1 mrg setlocale (LC_NUMERIC, old_locale);
4426 1.1 mrg old_locale = NULL;
4427 1.1 mrg }
4428 1.1 mrg __gthread_mutex_unlock (&old_locale_lock);
4429 1.1 mrg #endif
4430 1.1 mrg }
4431 1.1 mrg
4432 1.1 mrg /* Transfer function for IOLENGTH. It doesn't actually do any
4433 1.1 mrg data transfer, it just updates the length counter. */
4434 1.1 mrg
4435 1.1 mrg static void
4436 1.1 mrg iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
4437 1.1 mrg void *dest __attribute__ ((unused)),
4438 1.1 mrg int kind __attribute__((unused)),
4439 1.1 mrg size_t size, size_t nelems)
4440 1.1 mrg {
4441 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
4442 1.1 mrg *dtp->iolength += (GFC_IO_INT) (size * nelems);
4443 1.1 mrg }
4444 1.1 mrg
4445 1.1 mrg
4446 1.1 mrg /* Initialize the IOLENGTH data transfer. This function is in essence
4447 1.1 mrg a very much simplified version of data_transfer_init(), because it
4448 1.1 mrg doesn't have to deal with units at all. */
4449 1.1 mrg
4450 1.1 mrg static void
4451 1.1 mrg iolength_transfer_init (st_parameter_dt *dtp)
4452 1.1 mrg {
4453 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
4454 1.1 mrg *dtp->iolength = 0;
4455 1.1 mrg
4456 1.1 mrg memset (&dtp->u.p, 0, sizeof (dtp->u.p));
4457 1.1 mrg
4458 1.1 mrg /* Set up the subroutine that will handle the transfers. */
4459 1.1 mrg
4460 1.1 mrg dtp->u.p.transfer = iolength_transfer;
4461 1.1 mrg }
4462 1.1 mrg
4463 1.1 mrg
4464 1.1 mrg /* Library entry point for the IOLENGTH form of the INQUIRE
4465 1.1 mrg statement. The IOLENGTH form requires no I/O to be performed, but
4466 1.1 mrg it must still be a runtime library call so that we can determine
4467 1.1 mrg the iolength for dynamic arrays and such. */
4468 1.1 mrg
4469 1.1 mrg extern void st_iolength (st_parameter_dt *);
4470 1.1 mrg export_proto(st_iolength);
4471 1.1 mrg
4472 1.1 mrg void
4473 1.1 mrg st_iolength (st_parameter_dt *dtp)
4474 1.1 mrg {
4475 1.1 mrg library_start (&dtp->common);
4476 1.1 mrg iolength_transfer_init (dtp);
4477 1.1 mrg }
4478 1.1 mrg
4479 1.1 mrg extern void st_iolength_done (st_parameter_dt *);
4480 1.1 mrg export_proto(st_iolength_done);
4481 1.1 mrg
4482 1.1 mrg void
4483 1.1 mrg st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
4484 1.1 mrg {
4485 1.1 mrg free_ionml (dtp);
4486 1.1 mrg library_end ();
4487 1.1 mrg }
4488 1.1 mrg
4489 1.1 mrg
4490 1.1 mrg /* The READ statement. */
4491 1.1 mrg
4492 1.1 mrg extern void st_read (st_parameter_dt *);
4493 1.1 mrg export_proto(st_read);
4494 1.1 mrg
4495 1.1 mrg void
4496 1.1 mrg st_read (st_parameter_dt *dtp)
4497 1.1 mrg {
4498 1.1 mrg library_start (&dtp->common);
4499 1.1 mrg
4500 1.1 mrg data_transfer_init (dtp, 1);
4501 1.1 mrg }
4502 1.1 mrg
4503 1.1 mrg extern void st_read_done (st_parameter_dt *);
4504 1.1 mrg export_proto(st_read_done);
4505 1.1 mrg
4506 1.1 mrg void
4507 1.1.1.3 mrg st_read_done_worker (st_parameter_dt *dtp, bool unlock)
4508 1.1 mrg {
4509 1.1.1.3 mrg bool free_newunit = false;
4510 1.1 mrg finalize_transfer (dtp);
4511 1.1 mrg
4512 1.1 mrg free_ionml (dtp);
4513 1.1 mrg
4514 1.1 mrg /* If this is a parent READ statement we do not need to retain the
4515 1.1 mrg internal unit structure for child use. */
4516 1.1 mrg if (dtp->u.p.current_unit != NULL
4517 1.1 mrg && dtp->u.p.current_unit->child_dtio == 0)
4518 1.1 mrg {
4519 1.1 mrg if (dtp->u.p.unit_is_internal)
4520 1.1 mrg {
4521 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
4522 1.1 mrg {
4523 1.1 mrg free (dtp->u.p.current_unit->filename);
4524 1.1 mrg dtp->u.p.current_unit->filename = NULL;
4525 1.1 mrg if (dtp->u.p.current_unit->ls)
4526 1.1 mrg free (dtp->u.p.current_unit->ls);
4527 1.1 mrg dtp->u.p.current_unit->ls = NULL;
4528 1.1 mrg }
4529 1.1.1.3 mrg free_newunit = true;
4530 1.1 mrg }
4531 1.1 mrg if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
4532 1.1 mrg {
4533 1.1 mrg free_format_data (dtp->u.p.fmt);
4534 1.1 mrg free_format (dtp);
4535 1.1 mrg }
4536 1.1 mrg }
4537 1.1.1.3 mrg if (unlock)
4538 1.1.1.3 mrg unlock_unit (dtp->u.p.current_unit);
4539 1.1.1.3 mrg if (free_newunit)
4540 1.1.1.3 mrg {
4541 1.1.1.3 mrg /* Avoid inverse lock issues by placing after unlock_unit. */
4542 1.1.1.3 mrg LOCK (&unit_lock);
4543 1.1.1.3 mrg newunit_free (dtp->common.unit);
4544 1.1.1.3 mrg UNLOCK (&unit_lock);
4545 1.1.1.3 mrg }
4546 1.1 mrg }
4547 1.1 mrg
4548 1.1 mrg void
4549 1.1 mrg st_read_done (st_parameter_dt *dtp)
4550 1.1 mrg {
4551 1.1 mrg if (dtp->u.p.current_unit)
4552 1.1 mrg {
4553 1.1 mrg if (dtp->u.p.current_unit->au)
4554 1.1 mrg {
4555 1.1 mrg if (dtp->common.flags & IOPARM_DT_HAS_ID)
4556 1.1 mrg *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);
4557 1.1 mrg else
4558 1.1 mrg {
4559 1.1 mrg if (dtp->u.p.async)
4560 1.1 mrg enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
4561 1.1 mrg }
4562 1.1.1.3 mrg unlock_unit (dtp->u.p.current_unit);
4563 1.1 mrg }
4564 1.1 mrg else
4565 1.1.1.3 mrg st_read_done_worker (dtp, true); /* Calls unlock_unit. */
4566 1.1 mrg }
4567 1.1 mrg
4568 1.1 mrg library_end ();
4569 1.1 mrg }
4570 1.1 mrg
4571 1.1 mrg extern void st_write (st_parameter_dt *);
4572 1.1 mrg export_proto (st_write);
4573 1.1 mrg
4574 1.1 mrg void
4575 1.1 mrg st_write (st_parameter_dt *dtp)
4576 1.1 mrg {
4577 1.1 mrg library_start (&dtp->common);
4578 1.1 mrg data_transfer_init (dtp, 0);
4579 1.1 mrg }
4580 1.1 mrg
4581 1.1 mrg
4582 1.1 mrg void
4583 1.1.1.3 mrg st_write_done_worker (st_parameter_dt *dtp, bool unlock)
4584 1.1 mrg {
4585 1.1.1.3 mrg bool free_newunit = false;
4586 1.1 mrg finalize_transfer (dtp);
4587 1.1 mrg
4588 1.1 mrg if (dtp->u.p.current_unit != NULL
4589 1.1 mrg && dtp->u.p.current_unit->child_dtio == 0)
4590 1.1 mrg {
4591 1.1 mrg /* Deal with endfile conditions associated with sequential files. */
4592 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
4593 1.1 mrg switch (dtp->u.p.current_unit->endfile)
4594 1.1 mrg {
4595 1.1 mrg case AT_ENDFILE: /* Remain at the endfile record. */
4596 1.1 mrg break;
4597 1.1 mrg
4598 1.1 mrg case AFTER_ENDFILE:
4599 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now. */
4600 1.1 mrg break;
4601 1.1 mrg
4602 1.1 mrg case NO_ENDFILE:
4603 1.1 mrg /* Get rid of whatever is after this record. */
4604 1.1 mrg if (!is_internal_unit (dtp))
4605 1.1 mrg unit_truncate (dtp->u.p.current_unit,
4606 1.1 mrg stell (dtp->u.p.current_unit->s),
4607 1.1 mrg &dtp->common);
4608 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4609 1.1 mrg break;
4610 1.1 mrg }
4611 1.1 mrg
4612 1.1 mrg free_ionml (dtp);
4613 1.1 mrg
4614 1.1 mrg /* If this is a parent WRITE statement we do not need to retain the
4615 1.1 mrg internal unit structure for child use. */
4616 1.1 mrg if (dtp->u.p.unit_is_internal)
4617 1.1 mrg {
4618 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
4619 1.1 mrg {
4620 1.1 mrg free (dtp->u.p.current_unit->filename);
4621 1.1 mrg dtp->u.p.current_unit->filename = NULL;
4622 1.1 mrg if (dtp->u.p.current_unit->ls)
4623 1.1 mrg free (dtp->u.p.current_unit->ls);
4624 1.1 mrg dtp->u.p.current_unit->ls = NULL;
4625 1.1 mrg }
4626 1.1.1.3 mrg free_newunit = true;
4627 1.1 mrg }
4628 1.1 mrg if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
4629 1.1 mrg {
4630 1.1 mrg free_format_data (dtp->u.p.fmt);
4631 1.1 mrg free_format (dtp);
4632 1.1 mrg }
4633 1.1 mrg }
4634 1.1.1.3 mrg if (unlock)
4635 1.1.1.3 mrg unlock_unit (dtp->u.p.current_unit);
4636 1.1.1.3 mrg if (free_newunit)
4637 1.1.1.3 mrg {
4638 1.1.1.3 mrg /* Avoid inverse lock issues by placing after unlock_unit. */
4639 1.1.1.3 mrg LOCK (&unit_lock);
4640 1.1.1.3 mrg newunit_free (dtp->common.unit);
4641 1.1.1.3 mrg UNLOCK (&unit_lock);
4642 1.1.1.3 mrg }
4643 1.1 mrg }
4644 1.1 mrg
4645 1.1 mrg extern void st_write_done (st_parameter_dt *);
4646 1.1 mrg export_proto(st_write_done);
4647 1.1 mrg
4648 1.1 mrg void
4649 1.1 mrg st_write_done (st_parameter_dt *dtp)
4650 1.1 mrg {
4651 1.1 mrg if (dtp->u.p.current_unit)
4652 1.1 mrg {
4653 1.1 mrg if (dtp->u.p.current_unit->au && dtp->u.p.async)
4654 1.1 mrg {
4655 1.1 mrg if (dtp->common.flags & IOPARM_DT_HAS_ID)
4656 1.1 mrg *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
4657 1.1 mrg AIO_WRITE_DONE);
4658 1.1 mrg else
4659 1.1 mrg {
4660 1.1 mrg /* We perform synchronous I/O on an asynchronous unit, so no need
4661 1.1 mrg to enqueue AIO_READ_DONE. */
4662 1.1 mrg if (dtp->u.p.async)
4663 1.1 mrg enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
4664 1.1 mrg }
4665 1.1.1.3 mrg unlock_unit (dtp->u.p.current_unit);
4666 1.1 mrg }
4667 1.1 mrg else
4668 1.1.1.3 mrg st_write_done_worker (dtp, true); /* Calls unlock_unit. */
4669 1.1 mrg }
4670 1.1 mrg
4671 1.1 mrg library_end ();
4672 1.1 mrg }
4673 1.1 mrg
4674 1.1 mrg /* Wait operation. We need to keep around the do-nothing version
4675 1.1 mrg of st_wait for compatibility with previous versions, which had marked
4676 1.1 mrg the argument as unused (and thus liable to be removed).
4677 1.1 mrg
4678 1.1 mrg TODO: remove at next bump in version number. */
4679 1.1 mrg
4680 1.1 mrg void
4681 1.1 mrg st_wait (st_parameter_wait *wtp __attribute__((unused)))
4682 1.1 mrg {
4683 1.1 mrg return;
4684 1.1 mrg }
4685 1.1 mrg
4686 1.1 mrg void
4687 1.1 mrg st_wait_async (st_parameter_wait *wtp)
4688 1.1 mrg {
4689 1.1 mrg gfc_unit *u = find_unit (wtp->common.unit);
4690 1.1.1.2 mrg if (ASYNC_IO && u && u->au)
4691 1.1 mrg {
4692 1.1 mrg if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
4693 1.1 mrg async_wait_id (&(wtp->common), u->au, *wtp->id);
4694 1.1 mrg else
4695 1.1 mrg async_wait (&(wtp->common), u->au);
4696 1.1 mrg }
4697 1.1 mrg
4698 1.1 mrg unlock_unit (u);
4699 1.1 mrg }
4700 1.1 mrg
4701 1.1 mrg
4702 1.1 mrg /* Receives the scalar information for namelist objects and stores it
4703 1.1 mrg in a linked list of namelist_info types. */
4704 1.1 mrg
4705 1.1 mrg static void
4706 1.1 mrg set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
4707 1.1 mrg GFC_INTEGER_4 len, gfc_charlen_type string_length,
4708 1.1 mrg dtype_type dtype, void *dtio_sub, void *vtable)
4709 1.1 mrg {
4710 1.1 mrg namelist_info *t1 = NULL;
4711 1.1 mrg namelist_info *nml;
4712 1.1 mrg size_t var_name_len = strlen (var_name);
4713 1.1 mrg
4714 1.1 mrg nml = (namelist_info*) xmalloc (sizeof (namelist_info));
4715 1.1 mrg
4716 1.1 mrg nml->mem_pos = var_addr;
4717 1.1 mrg nml->dtio_sub = dtio_sub;
4718 1.1 mrg nml->vtable = vtable;
4719 1.1 mrg
4720 1.1 mrg nml->var_name = (char*) xmalloc (var_name_len + 1);
4721 1.1 mrg memcpy (nml->var_name, var_name, var_name_len);
4722 1.1 mrg nml->var_name[var_name_len] = '\0';
4723 1.1 mrg
4724 1.1 mrg nml->len = (int) len;
4725 1.1 mrg nml->string_length = (index_type) string_length;
4726 1.1 mrg
4727 1.1 mrg nml->var_rank = (int) (dtype.rank);
4728 1.1 mrg nml->size = (index_type) (dtype.elem_len);
4729 1.1 mrg nml->type = (bt) (dtype.type);
4730 1.1 mrg
4731 1.1 mrg if (nml->var_rank > 0)
4732 1.1 mrg {
4733 1.1 mrg nml->dim = (descriptor_dimension*)
4734 1.1 mrg xmallocarray (nml->var_rank, sizeof (descriptor_dimension));
4735 1.1 mrg nml->ls = (array_loop_spec*)
4736 1.1 mrg xmallocarray (nml->var_rank, sizeof (array_loop_spec));
4737 1.1 mrg }
4738 1.1 mrg else
4739 1.1 mrg {
4740 1.1 mrg nml->dim = NULL;
4741 1.1 mrg nml->ls = NULL;
4742 1.1 mrg }
4743 1.1 mrg
4744 1.1 mrg nml->next = NULL;
4745 1.1 mrg
4746 1.1 mrg if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
4747 1.1 mrg {
4748 1.1 mrg dtp->common.flags |= IOPARM_DT_IONML_SET;
4749 1.1 mrg dtp->u.p.ionml = nml;
4750 1.1 mrg }
4751 1.1 mrg else
4752 1.1 mrg {
4753 1.1 mrg for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
4754 1.1 mrg t1->next = nml;
4755 1.1 mrg }
4756 1.1 mrg }
4757 1.1 mrg
4758 1.1 mrg extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
4759 1.1 mrg GFC_INTEGER_4, gfc_charlen_type, dtype_type);
4760 1.1 mrg export_proto(st_set_nml_var);
4761 1.1 mrg
4762 1.1 mrg void
4763 1.1 mrg st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
4764 1.1 mrg GFC_INTEGER_4 len, gfc_charlen_type string_length,
4765 1.1 mrg dtype_type dtype)
4766 1.1 mrg {
4767 1.1 mrg set_nml_var (dtp, var_addr, var_name, len, string_length,
4768 1.1 mrg dtype, NULL, NULL);
4769 1.1 mrg }
4770 1.1 mrg
4771 1.1 mrg
4772 1.1 mrg /* Essentially the same as previous but carrying the dtio procedure
4773 1.1 mrg and the vtable as additional arguments. */
4774 1.1 mrg extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
4775 1.1 mrg GFC_INTEGER_4, gfc_charlen_type, dtype_type,
4776 1.1 mrg void *, void *);
4777 1.1 mrg export_proto(st_set_nml_dtio_var);
4778 1.1 mrg
4779 1.1 mrg
4780 1.1 mrg void
4781 1.1 mrg st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
4782 1.1 mrg GFC_INTEGER_4 len, gfc_charlen_type string_length,
4783 1.1 mrg dtype_type dtype, void *dtio_sub, void *vtable)
4784 1.1 mrg {
4785 1.1 mrg set_nml_var (dtp, var_addr, var_name, len, string_length,
4786 1.1 mrg dtype, dtio_sub, vtable);
4787 1.1 mrg }
4788 1.1 mrg
4789 1.1 mrg /* Store the dimensional information for the namelist object. */
4790 1.1 mrg extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
4791 1.1 mrg index_type, index_type,
4792 1.1 mrg index_type);
4793 1.1 mrg export_proto(st_set_nml_var_dim);
4794 1.1 mrg
4795 1.1 mrg void
4796 1.1 mrg st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
4797 1.1 mrg index_type stride, index_type lbound,
4798 1.1 mrg index_type ubound)
4799 1.1 mrg {
4800 1.1 mrg namelist_info *nml;
4801 1.1 mrg int n;
4802 1.1 mrg
4803 1.1 mrg n = (int)n_dim;
4804 1.1 mrg
4805 1.1 mrg for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);
4806 1.1 mrg
4807 1.1 mrg GFC_DIMENSION_SET(nml->dim[n],lbound,ubound,stride);
4808 1.1 mrg }
4809 1.1 mrg
4810 1.1 mrg
4811 1.1 mrg /* Once upon a time, a poor innocent Fortran program was reading a
4812 1.1 mrg file, when suddenly it hit the end-of-file (EOF). Unfortunately
4813 1.1 mrg the OS doesn't tell whether we're at the EOF or whether we already
4814 1.1 mrg went past it. Luckily our hero, libgfortran, keeps track of this.
4815 1.1 mrg Call this function when you detect an EOF condition. See Section
4816 1.1 mrg 9.10.2 in F2003. */
4817 1.1 mrg
4818 1.1 mrg void
4819 1.1 mrg hit_eof (st_parameter_dt *dtp)
4820 1.1 mrg {
4821 1.1 mrg dtp->u.p.current_unit->flags.position = POSITION_APPEND;
4822 1.1 mrg
4823 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
4824 1.1 mrg switch (dtp->u.p.current_unit->endfile)
4825 1.1 mrg {
4826 1.1 mrg case NO_ENDFILE:
4827 1.1 mrg case AT_ENDFILE:
4828 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
4829 1.1 mrg if (!is_internal_unit (dtp) && !dtp->u.p.namelist_mode)
4830 1.1 mrg {
4831 1.1 mrg dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
4832 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4833 1.1 mrg }
4834 1.1 mrg else
4835 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4836 1.1 mrg break;
4837 1.1 mrg
4838 1.1 mrg case AFTER_ENDFILE:
4839 1.1 mrg generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
4840 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4841 1.1 mrg break;
4842 1.1 mrg }
4843 1.1 mrg else
4844 1.1 mrg {
4845 1.1 mrg /* Non-sequential files don't have an ENDFILE record, so we
4846 1.1 mrg can't be at AFTER_ENDFILE. */
4847 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4848 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
4849 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4850 1.1 mrg }
4851 1.1 mrg }
4852