transfer.c revision 1.1.1.2 1 1.1.1.2 mrg /* Copyright (C) 2002-2020 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 mrg opened with PAD=YES. The caller must assume tailing 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 mrg if (type == BT_CLASS)
1092 1.1 mrg {
1093 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
1094 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
1095 1.1 mrg char *child_iomsg;
1096 1.1 mrg gfc_charlen_type child_iomsg_len;
1097 1.1 mrg int noiostat;
1098 1.1 mrg int *child_iostat = NULL;
1099 1.1 mrg
1100 1.1 mrg /* Set iostat, intent(out). */
1101 1.1 mrg noiostat = 0;
1102 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1103 1.1 mrg dtp->common.iostat : &noiostat;
1104 1.1 mrg
1105 1.1 mrg /* Set iomsg, intent(inout). */
1106 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
1107 1.1 mrg {
1108 1.1 mrg child_iomsg = dtp->common.iomsg;
1109 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
1110 1.1 mrg }
1111 1.1 mrg else
1112 1.1 mrg {
1113 1.1 mrg child_iomsg = tmp_iomsg;
1114 1.1 mrg child_iomsg_len = IOMSG_LEN;
1115 1.1 mrg }
1116 1.1 mrg
1117 1.1 mrg /* Call the user defined unformatted READ procedure. */
1118 1.1 mrg dtp->u.p.current_unit->child_dtio++;
1119 1.1 mrg dtp->u.p.ufdtio_ptr (dest, &unit, child_iostat, child_iomsg,
1120 1.1 mrg child_iomsg_len);
1121 1.1 mrg dtp->u.p.current_unit->child_dtio--;
1122 1.1 mrg return;
1123 1.1 mrg }
1124 1.1 mrg
1125 1.1 mrg if (type == BT_CHARACTER)
1126 1.1 mrg size *= GFC_SIZE_OF_CHAR_KIND(kind);
1127 1.1 mrg read_block_direct (dtp, dest, size * nelems);
1128 1.1 mrg
1129 1.1 mrg if (unlikely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_SWAP)
1130 1.1 mrg && kind != 1)
1131 1.1 mrg {
1132 1.1 mrg /* Handle wide chracters. */
1133 1.1 mrg if (type == BT_CHARACTER)
1134 1.1 mrg {
1135 1.1 mrg nelems *= size;
1136 1.1 mrg size = kind;
1137 1.1 mrg }
1138 1.1 mrg
1139 1.1 mrg /* Break up complex into its constituent reals. */
1140 1.1 mrg else if (type == BT_COMPLEX)
1141 1.1 mrg {
1142 1.1 mrg nelems *= 2;
1143 1.1 mrg size /= 2;
1144 1.1 mrg }
1145 1.1 mrg bswap_array (dest, dest, size, nelems);
1146 1.1 mrg }
1147 1.1 mrg }
1148 1.1 mrg
1149 1.1 mrg
1150 1.1 mrg /* Master function for unformatted writes. NOTE: For kind=10 the size is 16
1151 1.1 mrg bytes on 64 bit machines. The unused bytes are not initialized and never
1152 1.1 mrg used, which can show an error with memory checking analyzers like
1153 1.1 mrg valgrind. We us BT_CLASS to denote a User Defined I/O call. */
1154 1.1 mrg
1155 1.1 mrg static void
1156 1.1 mrg unformatted_write (st_parameter_dt *dtp, bt type,
1157 1.1 mrg void *source, int kind, size_t size, size_t nelems)
1158 1.1 mrg {
1159 1.1 mrg if (type == BT_CLASS)
1160 1.1 mrg {
1161 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
1162 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
1163 1.1 mrg char *child_iomsg;
1164 1.1 mrg gfc_charlen_type child_iomsg_len;
1165 1.1 mrg int noiostat;
1166 1.1 mrg int *child_iostat = NULL;
1167 1.1 mrg
1168 1.1 mrg /* Set iostat, intent(out). */
1169 1.1 mrg noiostat = 0;
1170 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1171 1.1 mrg dtp->common.iostat : &noiostat;
1172 1.1 mrg
1173 1.1 mrg /* Set iomsg, intent(inout). */
1174 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
1175 1.1 mrg {
1176 1.1 mrg child_iomsg = dtp->common.iomsg;
1177 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
1178 1.1 mrg }
1179 1.1 mrg else
1180 1.1 mrg {
1181 1.1 mrg child_iomsg = tmp_iomsg;
1182 1.1 mrg child_iomsg_len = IOMSG_LEN;
1183 1.1 mrg }
1184 1.1 mrg
1185 1.1 mrg /* Call the user defined unformatted WRITE procedure. */
1186 1.1 mrg dtp->u.p.current_unit->child_dtio++;
1187 1.1 mrg dtp->u.p.ufdtio_ptr (source, &unit, child_iostat, child_iomsg,
1188 1.1 mrg child_iomsg_len);
1189 1.1 mrg dtp->u.p.current_unit->child_dtio--;
1190 1.1 mrg return;
1191 1.1 mrg }
1192 1.1 mrg
1193 1.1 mrg if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE)
1194 1.1 mrg || kind == 1)
1195 1.1 mrg {
1196 1.1 mrg size_t stride = type == BT_CHARACTER ?
1197 1.1 mrg size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
1198 1.1 mrg
1199 1.1 mrg write_buf (dtp, source, stride * nelems);
1200 1.1 mrg }
1201 1.1 mrg else
1202 1.1 mrg {
1203 1.1 mrg #define BSWAP_BUFSZ 512
1204 1.1 mrg char buffer[BSWAP_BUFSZ];
1205 1.1 mrg char *p;
1206 1.1 mrg size_t nrem;
1207 1.1 mrg
1208 1.1 mrg p = source;
1209 1.1 mrg
1210 1.1 mrg /* Handle wide chracters. */
1211 1.1 mrg if (type == BT_CHARACTER && kind != 1)
1212 1.1 mrg {
1213 1.1 mrg nelems *= size;
1214 1.1 mrg size = kind;
1215 1.1 mrg }
1216 1.1 mrg
1217 1.1 mrg /* Break up complex into its constituent reals. */
1218 1.1 mrg if (type == BT_COMPLEX)
1219 1.1 mrg {
1220 1.1 mrg nelems *= 2;
1221 1.1 mrg size /= 2;
1222 1.1 mrg }
1223 1.1 mrg
1224 1.1 mrg /* By now, all complex variables have been split into their
1225 1.1 mrg constituent reals. */
1226 1.1 mrg
1227 1.1 mrg nrem = nelems;
1228 1.1 mrg do
1229 1.1 mrg {
1230 1.1 mrg size_t nc;
1231 1.1 mrg if (size * nrem > BSWAP_BUFSZ)
1232 1.1 mrg nc = BSWAP_BUFSZ / size;
1233 1.1 mrg else
1234 1.1 mrg nc = nrem;
1235 1.1 mrg
1236 1.1 mrg bswap_array (buffer, p, size, nc);
1237 1.1 mrg write_buf (dtp, buffer, size * nc);
1238 1.1 mrg p += size * nc;
1239 1.1 mrg nrem -= nc;
1240 1.1 mrg }
1241 1.1 mrg while (nrem > 0);
1242 1.1 mrg }
1243 1.1 mrg }
1244 1.1 mrg
1245 1.1 mrg
1246 1.1 mrg /* Return a pointer to the name of a type. */
1247 1.1 mrg
1248 1.1 mrg const char *
1249 1.1 mrg type_name (bt type)
1250 1.1 mrg {
1251 1.1 mrg const char *p;
1252 1.1 mrg
1253 1.1 mrg switch (type)
1254 1.1 mrg {
1255 1.1 mrg case BT_INTEGER:
1256 1.1 mrg p = "INTEGER";
1257 1.1 mrg break;
1258 1.1 mrg case BT_LOGICAL:
1259 1.1 mrg p = "LOGICAL";
1260 1.1 mrg break;
1261 1.1 mrg case BT_CHARACTER:
1262 1.1 mrg p = "CHARACTER";
1263 1.1 mrg break;
1264 1.1 mrg case BT_REAL:
1265 1.1 mrg p = "REAL";
1266 1.1 mrg break;
1267 1.1 mrg case BT_COMPLEX:
1268 1.1 mrg p = "COMPLEX";
1269 1.1 mrg break;
1270 1.1 mrg case BT_CLASS:
1271 1.1 mrg p = "CLASS or DERIVED";
1272 1.1 mrg break;
1273 1.1 mrg default:
1274 1.1 mrg internal_error (NULL, "type_name(): Bad type");
1275 1.1 mrg }
1276 1.1 mrg
1277 1.1 mrg return p;
1278 1.1 mrg }
1279 1.1 mrg
1280 1.1 mrg
1281 1.1 mrg /* Write a constant string to the output.
1282 1.1 mrg This is complicated because the string can have doubled delimiters
1283 1.1 mrg in it. The length in the format node is the true length. */
1284 1.1 mrg
1285 1.1 mrg static void
1286 1.1 mrg write_constant_string (st_parameter_dt *dtp, const fnode *f)
1287 1.1 mrg {
1288 1.1 mrg char c, delimiter, *p, *q;
1289 1.1 mrg int length;
1290 1.1 mrg
1291 1.1 mrg length = f->u.string.length;
1292 1.1 mrg if (length == 0)
1293 1.1 mrg return;
1294 1.1 mrg
1295 1.1 mrg p = write_block (dtp, length);
1296 1.1 mrg if (p == NULL)
1297 1.1 mrg return;
1298 1.1 mrg
1299 1.1 mrg q = f->u.string.p;
1300 1.1 mrg delimiter = q[-1];
1301 1.1 mrg
1302 1.1 mrg for (; length > 0; length--)
1303 1.1 mrg {
1304 1.1 mrg c = *p++ = *q++;
1305 1.1 mrg if (c == delimiter && c != 'H' && c != 'h')
1306 1.1 mrg q++; /* Skip the doubled delimiter. */
1307 1.1 mrg }
1308 1.1 mrg }
1309 1.1 mrg
1310 1.1 mrg
1311 1.1 mrg /* Given actual and expected types in a formatted data transfer, make
1312 1.1 mrg sure they agree. If not, an error message is generated. Returns
1313 1.1 mrg nonzero if something went wrong. */
1314 1.1 mrg
1315 1.1 mrg static int
1316 1.1 mrg require_type (st_parameter_dt *dtp, bt expected, bt actual, const fnode *f)
1317 1.1 mrg {
1318 1.1 mrg #define BUFLEN 100
1319 1.1 mrg char buffer[BUFLEN];
1320 1.1 mrg
1321 1.1 mrg if (actual == expected)
1322 1.1 mrg return 0;
1323 1.1 mrg
1324 1.1 mrg /* Adjust item_count before emitting error message. */
1325 1.1 mrg snprintf (buffer, BUFLEN,
1326 1.1 mrg "Expected %s for item %d in formatted transfer, got %s",
1327 1.1 mrg type_name (expected), dtp->u.p.item_count - 1, type_name (actual));
1328 1.1 mrg
1329 1.1 mrg format_error (dtp, f, buffer);
1330 1.1 mrg return 1;
1331 1.1 mrg }
1332 1.1 mrg
1333 1.1 mrg
1334 1.1 mrg /* Check that the dtio procedure required for formatted IO is present. */
1335 1.1 mrg
1336 1.1 mrg static int
1337 1.1 mrg check_dtio_proc (st_parameter_dt *dtp, const fnode *f)
1338 1.1 mrg {
1339 1.1 mrg char buffer[BUFLEN];
1340 1.1 mrg
1341 1.1 mrg if (dtp->u.p.fdtio_ptr != NULL)
1342 1.1 mrg return 0;
1343 1.1 mrg
1344 1.1 mrg snprintf (buffer, BUFLEN,
1345 1.1 mrg "Missing DTIO procedure or intrinsic type passed for item %d "
1346 1.1 mrg "in formatted transfer",
1347 1.1 mrg dtp->u.p.item_count - 1);
1348 1.1 mrg
1349 1.1 mrg format_error (dtp, f, buffer);
1350 1.1 mrg return 1;
1351 1.1 mrg }
1352 1.1 mrg
1353 1.1 mrg
1354 1.1 mrg static int
1355 1.1 mrg require_numeric_type (st_parameter_dt *dtp, bt actual, const fnode *f)
1356 1.1 mrg {
1357 1.1 mrg #define BUFLEN 100
1358 1.1 mrg char buffer[BUFLEN];
1359 1.1 mrg
1360 1.1 mrg if (actual == BT_INTEGER || actual == BT_REAL || actual == BT_COMPLEX)
1361 1.1 mrg return 0;
1362 1.1 mrg
1363 1.1 mrg /* Adjust item_count before emitting error message. */
1364 1.1 mrg snprintf (buffer, BUFLEN,
1365 1.1 mrg "Expected numeric type for item %d in formatted transfer, got %s",
1366 1.1 mrg dtp->u.p.item_count - 1, type_name (actual));
1367 1.1 mrg
1368 1.1 mrg format_error (dtp, f, buffer);
1369 1.1 mrg return 1;
1370 1.1 mrg }
1371 1.1 mrg
1372 1.1 mrg static char *
1373 1.1 mrg get_dt_format (char *p, gfc_charlen_type *length)
1374 1.1 mrg {
1375 1.1 mrg char delim = p[-1]; /* The delimiter is always the first character back. */
1376 1.1 mrg char c, *q, *res;
1377 1.1 mrg gfc_charlen_type len = *length; /* This length already correct, less 'DT'. */
1378 1.1 mrg
1379 1.1 mrg res = q = xmalloc (len + 2);
1380 1.1 mrg
1381 1.1 mrg /* Set the beginning of the string to 'DT', length adjusted below. */
1382 1.1 mrg *q++ = 'D';
1383 1.1 mrg *q++ = 'T';
1384 1.1 mrg
1385 1.1 mrg /* The string may contain doubled quotes so scan and skip as needed. */
1386 1.1 mrg for (; len > 0; len--)
1387 1.1 mrg {
1388 1.1 mrg c = *q++ = *p++;
1389 1.1 mrg if (c == delim)
1390 1.1 mrg p++; /* Skip the doubled delimiter. */
1391 1.1 mrg }
1392 1.1 mrg
1393 1.1 mrg /* Adjust the string length by two now that we are done. */
1394 1.1 mrg *length += 2;
1395 1.1 mrg
1396 1.1 mrg return res;
1397 1.1 mrg }
1398 1.1 mrg
1399 1.1 mrg
1400 1.1 mrg /* This function is in the main loop for a formatted data transfer
1401 1.1 mrg statement. It would be natural to implement this as a coroutine
1402 1.1 mrg with the user program, but C makes that awkward. We loop,
1403 1.1 mrg processing format elements. When we actually have to transfer
1404 1.1 mrg data instead of just setting flags, we return control to the user
1405 1.1 mrg program which calls a function that supplies the address and type
1406 1.1 mrg of the next element, then comes back here to process it. */
1407 1.1 mrg
1408 1.1 mrg static void
1409 1.1 mrg formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind,
1410 1.1 mrg size_t size)
1411 1.1 mrg {
1412 1.1 mrg int pos, bytes_used;
1413 1.1 mrg const fnode *f;
1414 1.1 mrg format_token t;
1415 1.1 mrg int n;
1416 1.1 mrg int consume_data_flag;
1417 1.1 mrg
1418 1.1 mrg /* Change a complex data item into a pair of reals. */
1419 1.1 mrg
1420 1.1 mrg n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
1421 1.1 mrg if (type == BT_COMPLEX)
1422 1.1 mrg {
1423 1.1 mrg type = BT_REAL;
1424 1.1 mrg size /= 2;
1425 1.1 mrg }
1426 1.1 mrg
1427 1.1 mrg /* If there's an EOR condition, we simulate finalizing the transfer
1428 1.1 mrg by doing nothing. */
1429 1.1 mrg if (dtp->u.p.eor_condition)
1430 1.1 mrg return;
1431 1.1 mrg
1432 1.1 mrg /* Set this flag so that commas in reads cause the read to complete before
1433 1.1 mrg the entire field has been read. The next read field will start right after
1434 1.1 mrg the comma in the stream. (Set to 0 for character reads). */
1435 1.1 mrg dtp->u.p.sf_read_comma =
1436 1.1 mrg dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
1437 1.1 mrg
1438 1.1 mrg for (;;)
1439 1.1 mrg {
1440 1.1 mrg /* If reversion has occurred and there is another real data item,
1441 1.1 mrg then we have to move to the next record. */
1442 1.1 mrg if (dtp->u.p.reversion_flag && n > 0)
1443 1.1 mrg {
1444 1.1 mrg dtp->u.p.reversion_flag = 0;
1445 1.1 mrg next_record (dtp, 0);
1446 1.1 mrg }
1447 1.1 mrg
1448 1.1 mrg consume_data_flag = 1;
1449 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1450 1.1 mrg break;
1451 1.1 mrg
1452 1.1 mrg f = next_format (dtp);
1453 1.1 mrg if (f == NULL)
1454 1.1 mrg {
1455 1.1 mrg /* No data descriptors left. */
1456 1.1 mrg if (unlikely (n > 0))
1457 1.1 mrg generate_error (&dtp->common, LIBERROR_FORMAT,
1458 1.1 mrg "Insufficient data descriptors in format after reversion");
1459 1.1 mrg return;
1460 1.1 mrg }
1461 1.1 mrg
1462 1.1 mrg t = f->format;
1463 1.1 mrg
1464 1.1 mrg bytes_used = (int)(dtp->u.p.current_unit->recl
1465 1.1 mrg - dtp->u.p.current_unit->bytes_left);
1466 1.1 mrg
1467 1.1 mrg if (is_stream_io(dtp))
1468 1.1 mrg bytes_used = 0;
1469 1.1 mrg
1470 1.1 mrg switch (t)
1471 1.1 mrg {
1472 1.1 mrg case FMT_I:
1473 1.1 mrg if (n == 0)
1474 1.1 mrg goto need_read_data;
1475 1.1 mrg if (require_type (dtp, BT_INTEGER, type, f))
1476 1.1 mrg return;
1477 1.1 mrg read_decimal (dtp, f, p, kind);
1478 1.1 mrg break;
1479 1.1 mrg
1480 1.1 mrg case FMT_B:
1481 1.1 mrg if (n == 0)
1482 1.1 mrg goto need_read_data;
1483 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1484 1.1 mrg && require_numeric_type (dtp, type, f))
1485 1.1 mrg return;
1486 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1487 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1488 1.1 mrg return;
1489 1.1 mrg read_radix (dtp, f, p, kind, 2);
1490 1.1 mrg break;
1491 1.1 mrg
1492 1.1 mrg case FMT_O:
1493 1.1 mrg if (n == 0)
1494 1.1 mrg goto need_read_data;
1495 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1496 1.1 mrg && require_numeric_type (dtp, type, f))
1497 1.1 mrg return;
1498 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1499 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1500 1.1 mrg return;
1501 1.1 mrg read_radix (dtp, f, p, kind, 8);
1502 1.1 mrg break;
1503 1.1 mrg
1504 1.1 mrg case FMT_Z:
1505 1.1 mrg if (n == 0)
1506 1.1 mrg goto need_read_data;
1507 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1508 1.1 mrg && require_numeric_type (dtp, type, f))
1509 1.1 mrg return;
1510 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1511 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1512 1.1 mrg return;
1513 1.1 mrg read_radix (dtp, f, p, kind, 16);
1514 1.1 mrg break;
1515 1.1 mrg
1516 1.1 mrg case FMT_A:
1517 1.1 mrg if (n == 0)
1518 1.1 mrg goto need_read_data;
1519 1.1 mrg
1520 1.1 mrg /* It is possible to have FMT_A with something not BT_CHARACTER such
1521 1.1 mrg as when writing out hollerith strings, so check both type
1522 1.1 mrg and kind before calling wide character routines. */
1523 1.1 mrg if (type == BT_CHARACTER && kind == 4)
1524 1.1 mrg read_a_char4 (dtp, f, p, size);
1525 1.1 mrg else
1526 1.1 mrg read_a (dtp, f, p, size);
1527 1.1 mrg break;
1528 1.1 mrg
1529 1.1 mrg case FMT_L:
1530 1.1 mrg if (n == 0)
1531 1.1 mrg goto need_read_data;
1532 1.1 mrg read_l (dtp, f, p, kind);
1533 1.1 mrg break;
1534 1.1 mrg
1535 1.1 mrg case FMT_D:
1536 1.1 mrg if (n == 0)
1537 1.1 mrg goto need_read_data;
1538 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1539 1.1 mrg return;
1540 1.1 mrg read_f (dtp, f, p, kind);
1541 1.1 mrg break;
1542 1.1 mrg
1543 1.1 mrg case FMT_DT:
1544 1.1 mrg if (n == 0)
1545 1.1 mrg goto need_read_data;
1546 1.1 mrg
1547 1.1 mrg if (check_dtio_proc (dtp, f))
1548 1.1 mrg return;
1549 1.1 mrg if (require_type (dtp, BT_CLASS, type, f))
1550 1.1 mrg return;
1551 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
1552 1.1 mrg char dt[] = "DT";
1553 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
1554 1.1 mrg char *child_iomsg;
1555 1.1 mrg gfc_charlen_type child_iomsg_len;
1556 1.1 mrg int noiostat;
1557 1.1 mrg int *child_iostat = NULL;
1558 1.1 mrg char *iotype;
1559 1.1 mrg gfc_charlen_type iotype_len = f->u.udf.string_len;
1560 1.1 mrg
1561 1.1 mrg /* Build the iotype string. */
1562 1.1 mrg if (iotype_len == 0)
1563 1.1 mrg {
1564 1.1 mrg iotype_len = 2;
1565 1.1 mrg iotype = dt;
1566 1.1 mrg }
1567 1.1 mrg else
1568 1.1 mrg iotype = get_dt_format (f->u.udf.string, &iotype_len);
1569 1.1 mrg
1570 1.1 mrg /* Set iostat, intent(out). */
1571 1.1 mrg noiostat = 0;
1572 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
1573 1.1 mrg dtp->common.iostat : &noiostat;
1574 1.1 mrg
1575 1.1 mrg /* Set iomsg, intent(inout). */
1576 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
1577 1.1 mrg {
1578 1.1 mrg child_iomsg = dtp->common.iomsg;
1579 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
1580 1.1 mrg }
1581 1.1 mrg else
1582 1.1 mrg {
1583 1.1 mrg child_iomsg = tmp_iomsg;
1584 1.1 mrg child_iomsg_len = IOMSG_LEN;
1585 1.1 mrg }
1586 1.1 mrg
1587 1.1 mrg /* Call the user defined formatted READ procedure. */
1588 1.1 mrg dtp->u.p.current_unit->child_dtio++;
1589 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
1590 1.1 mrg dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
1591 1.1 mrg child_iostat, child_iomsg,
1592 1.1 mrg iotype_len, child_iomsg_len);
1593 1.1 mrg dtp->u.p.current_unit->child_dtio--;
1594 1.1 mrg
1595 1.1 mrg if (f->u.udf.string_len != 0)
1596 1.1 mrg free (iotype);
1597 1.1 mrg /* Note: vlist is freed in free_format_data. */
1598 1.1 mrg break;
1599 1.1 mrg
1600 1.1 mrg case FMT_E:
1601 1.1 mrg if (n == 0)
1602 1.1 mrg goto need_read_data;
1603 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1604 1.1 mrg return;
1605 1.1 mrg read_f (dtp, f, p, kind);
1606 1.1 mrg break;
1607 1.1 mrg
1608 1.1 mrg case FMT_EN:
1609 1.1 mrg if (n == 0)
1610 1.1 mrg goto need_read_data;
1611 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1612 1.1 mrg return;
1613 1.1 mrg read_f (dtp, f, p, kind);
1614 1.1 mrg break;
1615 1.1 mrg
1616 1.1 mrg case FMT_ES:
1617 1.1 mrg if (n == 0)
1618 1.1 mrg goto need_read_data;
1619 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1620 1.1 mrg return;
1621 1.1 mrg read_f (dtp, f, p, kind);
1622 1.1 mrg break;
1623 1.1 mrg
1624 1.1 mrg case FMT_F:
1625 1.1 mrg if (n == 0)
1626 1.1 mrg goto need_read_data;
1627 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
1628 1.1 mrg return;
1629 1.1 mrg read_f (dtp, f, p, kind);
1630 1.1 mrg break;
1631 1.1 mrg
1632 1.1 mrg case FMT_G:
1633 1.1 mrg if (n == 0)
1634 1.1 mrg goto need_read_data;
1635 1.1 mrg switch (type)
1636 1.1 mrg {
1637 1.1 mrg case BT_INTEGER:
1638 1.1 mrg read_decimal (dtp, f, p, kind);
1639 1.1 mrg break;
1640 1.1 mrg case BT_LOGICAL:
1641 1.1 mrg read_l (dtp, f, p, kind);
1642 1.1 mrg break;
1643 1.1 mrg case BT_CHARACTER:
1644 1.1 mrg if (kind == 4)
1645 1.1 mrg read_a_char4 (dtp, f, p, size);
1646 1.1 mrg else
1647 1.1 mrg read_a (dtp, f, p, size);
1648 1.1 mrg break;
1649 1.1 mrg case BT_REAL:
1650 1.1 mrg read_f (dtp, f, p, kind);
1651 1.1 mrg break;
1652 1.1 mrg default:
1653 1.1 mrg internal_error (&dtp->common,
1654 1.1 mrg "formatted_transfer (): Bad type");
1655 1.1 mrg }
1656 1.1 mrg break;
1657 1.1 mrg
1658 1.1 mrg case FMT_STRING:
1659 1.1 mrg consume_data_flag = 0;
1660 1.1 mrg format_error (dtp, f, "Constant string in input format");
1661 1.1 mrg return;
1662 1.1 mrg
1663 1.1 mrg /* Format codes that don't transfer data. */
1664 1.1 mrg case FMT_X:
1665 1.1 mrg case FMT_TR:
1666 1.1 mrg consume_data_flag = 0;
1667 1.1 mrg dtp->u.p.skips += f->u.n;
1668 1.1 mrg pos = bytes_used + dtp->u.p.skips - 1;
1669 1.1 mrg dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
1670 1.1 mrg read_x (dtp, f->u.n);
1671 1.1 mrg break;
1672 1.1 mrg
1673 1.1 mrg case FMT_TL:
1674 1.1 mrg case FMT_T:
1675 1.1 mrg consume_data_flag = 0;
1676 1.1 mrg
1677 1.1 mrg if (f->format == FMT_TL)
1678 1.1 mrg {
1679 1.1 mrg /* Handle the special case when no bytes have been used yet.
1680 1.1 mrg Cannot go below zero. */
1681 1.1 mrg if (bytes_used == 0)
1682 1.1 mrg {
1683 1.1 mrg dtp->u.p.pending_spaces -= f->u.n;
1684 1.1 mrg dtp->u.p.skips -= f->u.n;
1685 1.1 mrg dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
1686 1.1 mrg }
1687 1.1 mrg
1688 1.1 mrg pos = bytes_used - f->u.n;
1689 1.1 mrg }
1690 1.1 mrg else /* FMT_T */
1691 1.1 mrg pos = f->u.n - 1;
1692 1.1 mrg
1693 1.1 mrg /* Standard 10.6.1.1: excessive left tabbing is reset to the
1694 1.1 mrg left tab limit. We do not check if the position has gone
1695 1.1 mrg beyond the end of record because a subsequent tab could
1696 1.1 mrg bring us back again. */
1697 1.1 mrg pos = pos < 0 ? 0 : pos;
1698 1.1 mrg
1699 1.1 mrg dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
1700 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
1701 1.1 mrg + pos - dtp->u.p.max_pos;
1702 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
1703 1.1 mrg ? 0 : dtp->u.p.pending_spaces;
1704 1.1 mrg if (dtp->u.p.skips == 0)
1705 1.1 mrg break;
1706 1.1 mrg
1707 1.1 mrg /* Adjust everything for end-of-record condition */
1708 1.1 mrg if (dtp->u.p.sf_seen_eor && !is_internal_unit (dtp))
1709 1.1 mrg {
1710 1.1 mrg dtp->u.p.current_unit->bytes_left -= dtp->u.p.sf_seen_eor;
1711 1.1 mrg dtp->u.p.skips -= dtp->u.p.sf_seen_eor;
1712 1.1 mrg bytes_used = pos;
1713 1.1 mrg if (dtp->u.p.pending_spaces == 0)
1714 1.1 mrg dtp->u.p.sf_seen_eor = 0;
1715 1.1 mrg }
1716 1.1 mrg if (dtp->u.p.skips < 0)
1717 1.1 mrg {
1718 1.1 mrg if (is_internal_unit (dtp))
1719 1.1 mrg sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
1720 1.1 mrg else
1721 1.1 mrg fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
1722 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
1723 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1724 1.1 mrg }
1725 1.1 mrg else
1726 1.1 mrg read_x (dtp, dtp->u.p.skips);
1727 1.1 mrg break;
1728 1.1 mrg
1729 1.1 mrg case FMT_S:
1730 1.1 mrg consume_data_flag = 0;
1731 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PROCDEFINED;
1732 1.1 mrg break;
1733 1.1 mrg
1734 1.1 mrg case FMT_SS:
1735 1.1 mrg consume_data_flag = 0;
1736 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_SUPPRESS;
1737 1.1 mrg break;
1738 1.1 mrg
1739 1.1 mrg case FMT_SP:
1740 1.1 mrg consume_data_flag = 0;
1741 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PLUS;
1742 1.1 mrg break;
1743 1.1 mrg
1744 1.1 mrg case FMT_BN:
1745 1.1 mrg consume_data_flag = 0 ;
1746 1.1 mrg dtp->u.p.blank_status = BLANK_NULL;
1747 1.1 mrg break;
1748 1.1 mrg
1749 1.1 mrg case FMT_BZ:
1750 1.1 mrg consume_data_flag = 0;
1751 1.1 mrg dtp->u.p.blank_status = BLANK_ZERO;
1752 1.1 mrg break;
1753 1.1 mrg
1754 1.1 mrg case FMT_DC:
1755 1.1 mrg consume_data_flag = 0;
1756 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
1757 1.1 mrg break;
1758 1.1 mrg
1759 1.1 mrg case FMT_DP:
1760 1.1 mrg consume_data_flag = 0;
1761 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
1762 1.1 mrg break;
1763 1.1 mrg
1764 1.1 mrg case FMT_RC:
1765 1.1 mrg consume_data_flag = 0;
1766 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
1767 1.1 mrg break;
1768 1.1 mrg
1769 1.1 mrg case FMT_RD:
1770 1.1 mrg consume_data_flag = 0;
1771 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_DOWN;
1772 1.1 mrg break;
1773 1.1 mrg
1774 1.1 mrg case FMT_RN:
1775 1.1 mrg consume_data_flag = 0;
1776 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_NEAREST;
1777 1.1 mrg break;
1778 1.1 mrg
1779 1.1 mrg case FMT_RP:
1780 1.1 mrg consume_data_flag = 0;
1781 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
1782 1.1 mrg break;
1783 1.1 mrg
1784 1.1 mrg case FMT_RU:
1785 1.1 mrg consume_data_flag = 0;
1786 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_UP;
1787 1.1 mrg break;
1788 1.1 mrg
1789 1.1 mrg case FMT_RZ:
1790 1.1 mrg consume_data_flag = 0;
1791 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_ZERO;
1792 1.1 mrg break;
1793 1.1 mrg
1794 1.1 mrg case FMT_P:
1795 1.1 mrg consume_data_flag = 0;
1796 1.1 mrg dtp->u.p.scale_factor = f->u.k;
1797 1.1 mrg break;
1798 1.1 mrg
1799 1.1 mrg case FMT_DOLLAR:
1800 1.1 mrg consume_data_flag = 0;
1801 1.1 mrg dtp->u.p.seen_dollar = 1;
1802 1.1 mrg break;
1803 1.1 mrg
1804 1.1 mrg case FMT_SLASH:
1805 1.1 mrg consume_data_flag = 0;
1806 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1807 1.1 mrg next_record (dtp, 0);
1808 1.1 mrg break;
1809 1.1 mrg
1810 1.1 mrg case FMT_COLON:
1811 1.1 mrg /* A colon descriptor causes us to exit this loop (in
1812 1.1 mrg particular preventing another / descriptor from being
1813 1.1 mrg processed) unless there is another data item to be
1814 1.1 mrg transferred. */
1815 1.1 mrg consume_data_flag = 0;
1816 1.1 mrg if (n == 0)
1817 1.1 mrg return;
1818 1.1 mrg break;
1819 1.1 mrg
1820 1.1 mrg default:
1821 1.1 mrg internal_error (&dtp->common, "Bad format node");
1822 1.1 mrg }
1823 1.1 mrg
1824 1.1 mrg /* Adjust the item count and data pointer. */
1825 1.1 mrg
1826 1.1 mrg if ((consume_data_flag > 0) && (n > 0))
1827 1.1 mrg {
1828 1.1 mrg n--;
1829 1.1 mrg p = ((char *) p) + size;
1830 1.1 mrg }
1831 1.1 mrg
1832 1.1 mrg dtp->u.p.skips = 0;
1833 1.1 mrg
1834 1.1 mrg pos = (int)(dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left);
1835 1.1 mrg dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
1836 1.1 mrg }
1837 1.1 mrg
1838 1.1 mrg return;
1839 1.1 mrg
1840 1.1 mrg /* Come here when we need a data descriptor but don't have one. We
1841 1.1 mrg push the current format node back onto the input, then return and
1842 1.1 mrg let the user program call us back with the data. */
1843 1.1 mrg need_read_data:
1844 1.1 mrg unget_format (dtp, f);
1845 1.1 mrg }
1846 1.1 mrg
1847 1.1 mrg
1848 1.1 mrg static void
1849 1.1 mrg formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kind,
1850 1.1 mrg size_t size)
1851 1.1 mrg {
1852 1.1 mrg gfc_offset pos, bytes_used;
1853 1.1 mrg const fnode *f;
1854 1.1 mrg format_token t;
1855 1.1 mrg int n;
1856 1.1 mrg int consume_data_flag;
1857 1.1 mrg
1858 1.1 mrg /* Change a complex data item into a pair of reals. */
1859 1.1 mrg
1860 1.1 mrg n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
1861 1.1 mrg if (type == BT_COMPLEX)
1862 1.1 mrg {
1863 1.1 mrg type = BT_REAL;
1864 1.1 mrg size /= 2;
1865 1.1 mrg }
1866 1.1 mrg
1867 1.1 mrg /* If there's an EOR condition, we simulate finalizing the transfer
1868 1.1 mrg by doing nothing. */
1869 1.1 mrg if (dtp->u.p.eor_condition)
1870 1.1 mrg return;
1871 1.1 mrg
1872 1.1 mrg /* Set this flag so that commas in reads cause the read to complete before
1873 1.1 mrg the entire field has been read. The next read field will start right after
1874 1.1 mrg the comma in the stream. (Set to 0 for character reads). */
1875 1.1 mrg dtp->u.p.sf_read_comma =
1876 1.1 mrg dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA ? 0 : 1;
1877 1.1 mrg
1878 1.1 mrg for (;;)
1879 1.1 mrg {
1880 1.1 mrg /* If reversion has occurred and there is another real data item,
1881 1.1 mrg then we have to move to the next record. */
1882 1.1 mrg if (dtp->u.p.reversion_flag && n > 0)
1883 1.1 mrg {
1884 1.1 mrg dtp->u.p.reversion_flag = 0;
1885 1.1 mrg next_record (dtp, 0);
1886 1.1 mrg }
1887 1.1 mrg
1888 1.1 mrg consume_data_flag = 1;
1889 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
1890 1.1 mrg break;
1891 1.1 mrg
1892 1.1 mrg f = next_format (dtp);
1893 1.1 mrg if (f == NULL)
1894 1.1 mrg {
1895 1.1 mrg /* No data descriptors left. */
1896 1.1 mrg if (unlikely (n > 0))
1897 1.1 mrg generate_error (&dtp->common, LIBERROR_FORMAT,
1898 1.1 mrg "Insufficient data descriptors in format after reversion");
1899 1.1 mrg return;
1900 1.1 mrg }
1901 1.1 mrg
1902 1.1 mrg /* Now discharge T, TR and X movements to the right. This is delayed
1903 1.1 mrg until a data producing format to suppress trailing spaces. */
1904 1.1 mrg
1905 1.1 mrg t = f->format;
1906 1.1 mrg if (dtp->u.p.mode == WRITING && dtp->u.p.skips != 0
1907 1.1 mrg && ((n>0 && ( t == FMT_I || t == FMT_B || t == FMT_O
1908 1.1 mrg || t == FMT_Z || t == FMT_F || t == FMT_E
1909 1.1 mrg || t == FMT_EN || t == FMT_ES || t == FMT_G
1910 1.1 mrg || t == FMT_L || t == FMT_A || t == FMT_D
1911 1.1 mrg || t == FMT_DT))
1912 1.1 mrg || t == FMT_STRING))
1913 1.1 mrg {
1914 1.1 mrg if (dtp->u.p.skips > 0)
1915 1.1 mrg {
1916 1.1 mrg gfc_offset tmp;
1917 1.1 mrg write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
1918 1.1 mrg tmp = dtp->u.p.current_unit->recl
1919 1.1 mrg - dtp->u.p.current_unit->bytes_left;
1920 1.1 mrg dtp->u.p.max_pos =
1921 1.1 mrg dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
1922 1.1 mrg dtp->u.p.skips = 0;
1923 1.1 mrg }
1924 1.1 mrg if (dtp->u.p.skips < 0)
1925 1.1 mrg {
1926 1.1 mrg if (is_internal_unit (dtp))
1927 1.1 mrg sseek (dtp->u.p.current_unit->s, dtp->u.p.skips, SEEK_CUR);
1928 1.1 mrg else
1929 1.1 mrg fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips, SEEK_CUR);
1930 1.1 mrg dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
1931 1.1 mrg }
1932 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
1933 1.1 mrg }
1934 1.1 mrg
1935 1.1 mrg bytes_used = dtp->u.p.current_unit->recl
1936 1.1 mrg - dtp->u.p.current_unit->bytes_left;
1937 1.1 mrg
1938 1.1 mrg if (is_stream_io(dtp))
1939 1.1 mrg bytes_used = 0;
1940 1.1 mrg
1941 1.1 mrg switch (t)
1942 1.1 mrg {
1943 1.1 mrg case FMT_I:
1944 1.1 mrg if (n == 0)
1945 1.1 mrg goto need_data;
1946 1.1 mrg if (require_type (dtp, BT_INTEGER, type, f))
1947 1.1 mrg return;
1948 1.1 mrg write_i (dtp, f, p, kind);
1949 1.1 mrg break;
1950 1.1 mrg
1951 1.1 mrg case FMT_B:
1952 1.1 mrg if (n == 0)
1953 1.1 mrg goto need_data;
1954 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1955 1.1 mrg && require_numeric_type (dtp, type, f))
1956 1.1 mrg return;
1957 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1958 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1959 1.1 mrg return;
1960 1.1 mrg write_b (dtp, f, p, kind);
1961 1.1 mrg break;
1962 1.1 mrg
1963 1.1 mrg case FMT_O:
1964 1.1 mrg if (n == 0)
1965 1.1 mrg goto need_data;
1966 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1967 1.1 mrg && require_numeric_type (dtp, type, f))
1968 1.1 mrg return;
1969 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1970 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1971 1.1 mrg return;
1972 1.1 mrg write_o (dtp, f, p, kind);
1973 1.1 mrg break;
1974 1.1 mrg
1975 1.1 mrg case FMT_Z:
1976 1.1 mrg if (n == 0)
1977 1.1 mrg goto need_data;
1978 1.1 mrg if (!(compile_options.allow_std & GFC_STD_GNU)
1979 1.1 mrg && require_numeric_type (dtp, type, f))
1980 1.1 mrg return;
1981 1.1 mrg if (!(compile_options.allow_std & GFC_STD_F2008)
1982 1.1 mrg && require_type (dtp, BT_INTEGER, type, f))
1983 1.1 mrg return;
1984 1.1 mrg write_z (dtp, f, p, kind);
1985 1.1 mrg break;
1986 1.1 mrg
1987 1.1 mrg case FMT_A:
1988 1.1 mrg if (n == 0)
1989 1.1 mrg goto need_data;
1990 1.1 mrg
1991 1.1 mrg /* It is possible to have FMT_A with something not BT_CHARACTER such
1992 1.1 mrg as when writing out hollerith strings, so check both type
1993 1.1 mrg and kind before calling wide character routines. */
1994 1.1 mrg if (type == BT_CHARACTER && kind == 4)
1995 1.1 mrg write_a_char4 (dtp, f, p, size);
1996 1.1 mrg else
1997 1.1 mrg write_a (dtp, f, p, size);
1998 1.1 mrg break;
1999 1.1 mrg
2000 1.1 mrg case FMT_L:
2001 1.1 mrg if (n == 0)
2002 1.1 mrg goto need_data;
2003 1.1 mrg write_l (dtp, f, p, kind);
2004 1.1 mrg break;
2005 1.1 mrg
2006 1.1 mrg case FMT_D:
2007 1.1 mrg if (n == 0)
2008 1.1 mrg goto need_data;
2009 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2010 1.1 mrg return;
2011 1.1.1.2 mrg if (f->u.real.w == 0)
2012 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2013 1.1.1.2 mrg else
2014 1.1.1.2 mrg write_d (dtp, f, p, kind);
2015 1.1 mrg break;
2016 1.1 mrg
2017 1.1 mrg case FMT_DT:
2018 1.1 mrg if (n == 0)
2019 1.1 mrg goto need_data;
2020 1.1 mrg int unit = dtp->u.p.current_unit->unit_number;
2021 1.1 mrg char dt[] = "DT";
2022 1.1 mrg char tmp_iomsg[IOMSG_LEN] = "";
2023 1.1 mrg char *child_iomsg;
2024 1.1 mrg gfc_charlen_type child_iomsg_len;
2025 1.1 mrg int noiostat;
2026 1.1 mrg int *child_iostat = NULL;
2027 1.1 mrg char *iotype;
2028 1.1 mrg gfc_charlen_type iotype_len = f->u.udf.string_len;
2029 1.1 mrg
2030 1.1 mrg /* Build the iotype string. */
2031 1.1 mrg if (iotype_len == 0)
2032 1.1 mrg {
2033 1.1 mrg iotype_len = 2;
2034 1.1 mrg iotype = dt;
2035 1.1 mrg }
2036 1.1 mrg else
2037 1.1 mrg iotype = get_dt_format (f->u.udf.string, &iotype_len);
2038 1.1 mrg
2039 1.1 mrg /* Set iostat, intent(out). */
2040 1.1 mrg noiostat = 0;
2041 1.1 mrg child_iostat = (dtp->common.flags & IOPARM_HAS_IOSTAT) ?
2042 1.1 mrg dtp->common.iostat : &noiostat;
2043 1.1 mrg
2044 1.1 mrg /* Set iomsg, intent(inout). */
2045 1.1 mrg if (dtp->common.flags & IOPARM_HAS_IOMSG)
2046 1.1 mrg {
2047 1.1 mrg child_iomsg = dtp->common.iomsg;
2048 1.1 mrg child_iomsg_len = dtp->common.iomsg_len;
2049 1.1 mrg }
2050 1.1 mrg else
2051 1.1 mrg {
2052 1.1 mrg child_iomsg = tmp_iomsg;
2053 1.1 mrg child_iomsg_len = IOMSG_LEN;
2054 1.1 mrg }
2055 1.1 mrg
2056 1.1 mrg if (check_dtio_proc (dtp, f))
2057 1.1 mrg return;
2058 1.1 mrg
2059 1.1 mrg /* Call the user defined formatted WRITE procedure. */
2060 1.1 mrg dtp->u.p.current_unit->child_dtio++;
2061 1.1 mrg
2062 1.1 mrg dtp->u.p.fdtio_ptr (p, &unit, iotype, f->u.udf.vlist,
2063 1.1 mrg child_iostat, child_iomsg,
2064 1.1 mrg iotype_len, child_iomsg_len);
2065 1.1 mrg dtp->u.p.current_unit->child_dtio--;
2066 1.1 mrg
2067 1.1 mrg if (f->u.udf.string_len != 0)
2068 1.1 mrg free (iotype);
2069 1.1 mrg /* Note: vlist is freed in free_format_data. */
2070 1.1 mrg break;
2071 1.1 mrg
2072 1.1 mrg case FMT_E:
2073 1.1 mrg if (n == 0)
2074 1.1 mrg goto need_data;
2075 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2076 1.1 mrg return;
2077 1.1.1.2 mrg if (f->u.real.w == 0)
2078 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2079 1.1.1.2 mrg else
2080 1.1.1.2 mrg write_e (dtp, f, p, kind);
2081 1.1 mrg break;
2082 1.1 mrg
2083 1.1 mrg case FMT_EN:
2084 1.1 mrg if (n == 0)
2085 1.1 mrg goto need_data;
2086 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2087 1.1 mrg return;
2088 1.1.1.2 mrg if (f->u.real.w == 0)
2089 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2090 1.1.1.2 mrg else
2091 1.1.1.2 mrg write_en (dtp, f, p, kind);
2092 1.1 mrg break;
2093 1.1 mrg
2094 1.1 mrg case FMT_ES:
2095 1.1 mrg if (n == 0)
2096 1.1 mrg goto need_data;
2097 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2098 1.1 mrg return;
2099 1.1.1.2 mrg if (f->u.real.w == 0)
2100 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2101 1.1.1.2 mrg else
2102 1.1.1.2 mrg write_es (dtp, f, p, kind);
2103 1.1 mrg break;
2104 1.1 mrg
2105 1.1 mrg case FMT_F:
2106 1.1 mrg if (n == 0)
2107 1.1 mrg goto need_data;
2108 1.1 mrg if (require_type (dtp, BT_REAL, type, f))
2109 1.1 mrg return;
2110 1.1 mrg write_f (dtp, f, p, kind);
2111 1.1 mrg break;
2112 1.1 mrg
2113 1.1 mrg case FMT_G:
2114 1.1 mrg if (n == 0)
2115 1.1 mrg goto need_data;
2116 1.1 mrg switch (type)
2117 1.1 mrg {
2118 1.1 mrg case BT_INTEGER:
2119 1.1 mrg write_i (dtp, f, p, kind);
2120 1.1 mrg break;
2121 1.1 mrg case BT_LOGICAL:
2122 1.1 mrg write_l (dtp, f, p, kind);
2123 1.1 mrg break;
2124 1.1 mrg case BT_CHARACTER:
2125 1.1 mrg if (kind == 4)
2126 1.1 mrg write_a_char4 (dtp, f, p, size);
2127 1.1 mrg else
2128 1.1 mrg write_a (dtp, f, p, size);
2129 1.1 mrg break;
2130 1.1 mrg case BT_REAL:
2131 1.1 mrg if (f->u.real.w == 0)
2132 1.1.1.2 mrg write_real_w0 (dtp, p, kind, f);
2133 1.1 mrg else
2134 1.1 mrg write_d (dtp, f, p, kind);
2135 1.1 mrg break;
2136 1.1 mrg default:
2137 1.1 mrg internal_error (&dtp->common,
2138 1.1 mrg "formatted_transfer (): Bad type");
2139 1.1 mrg }
2140 1.1 mrg break;
2141 1.1 mrg
2142 1.1 mrg case FMT_STRING:
2143 1.1 mrg consume_data_flag = 0;
2144 1.1 mrg write_constant_string (dtp, f);
2145 1.1 mrg break;
2146 1.1 mrg
2147 1.1 mrg /* Format codes that don't transfer data. */
2148 1.1 mrg case FMT_X:
2149 1.1 mrg case FMT_TR:
2150 1.1 mrg consume_data_flag = 0;
2151 1.1 mrg
2152 1.1 mrg dtp->u.p.skips += f->u.n;
2153 1.1 mrg pos = bytes_used + dtp->u.p.skips - 1;
2154 1.1 mrg dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1;
2155 1.1 mrg /* Writes occur just before the switch on f->format, above, so
2156 1.1 mrg that trailing blanks are suppressed, unless we are doing a
2157 1.1 mrg non-advancing write in which case we want to output the blanks
2158 1.1 mrg now. */
2159 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO)
2160 1.1 mrg {
2161 1.1 mrg write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
2162 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2163 1.1 mrg }
2164 1.1 mrg break;
2165 1.1 mrg
2166 1.1 mrg case FMT_TL:
2167 1.1 mrg case FMT_T:
2168 1.1 mrg consume_data_flag = 0;
2169 1.1 mrg
2170 1.1 mrg if (f->format == FMT_TL)
2171 1.1 mrg {
2172 1.1 mrg
2173 1.1 mrg /* Handle the special case when no bytes have been used yet.
2174 1.1 mrg Cannot go below zero. */
2175 1.1 mrg if (bytes_used == 0)
2176 1.1 mrg {
2177 1.1 mrg dtp->u.p.pending_spaces -= f->u.n;
2178 1.1 mrg dtp->u.p.skips -= f->u.n;
2179 1.1 mrg dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips;
2180 1.1 mrg }
2181 1.1 mrg
2182 1.1 mrg pos = bytes_used - f->u.n;
2183 1.1 mrg }
2184 1.1 mrg else /* FMT_T */
2185 1.1 mrg pos = f->u.n - dtp->u.p.pending_spaces - 1;
2186 1.1 mrg
2187 1.1 mrg /* Standard 10.6.1.1: excessive left tabbing is reset to the
2188 1.1 mrg left tab limit. We do not check if the position has gone
2189 1.1 mrg beyond the end of record because a subsequent tab could
2190 1.1 mrg bring us back again. */
2191 1.1 mrg pos = pos < 0 ? 0 : pos;
2192 1.1 mrg
2193 1.1 mrg dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used;
2194 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces
2195 1.1 mrg + pos - dtp->u.p.max_pos;
2196 1.1 mrg dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0
2197 1.1 mrg ? 0 : dtp->u.p.pending_spaces;
2198 1.1 mrg break;
2199 1.1 mrg
2200 1.1 mrg case FMT_S:
2201 1.1 mrg consume_data_flag = 0;
2202 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PROCDEFINED;
2203 1.1 mrg break;
2204 1.1 mrg
2205 1.1 mrg case FMT_SS:
2206 1.1 mrg consume_data_flag = 0;
2207 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_SUPPRESS;
2208 1.1 mrg break;
2209 1.1 mrg
2210 1.1 mrg case FMT_SP:
2211 1.1 mrg consume_data_flag = 0;
2212 1.1.1.2 mrg dtp->u.p.sign_status = SIGN_PLUS;
2213 1.1 mrg break;
2214 1.1 mrg
2215 1.1 mrg case FMT_BN:
2216 1.1 mrg consume_data_flag = 0 ;
2217 1.1 mrg dtp->u.p.blank_status = BLANK_NULL;
2218 1.1 mrg break;
2219 1.1 mrg
2220 1.1 mrg case FMT_BZ:
2221 1.1 mrg consume_data_flag = 0;
2222 1.1 mrg dtp->u.p.blank_status = BLANK_ZERO;
2223 1.1 mrg break;
2224 1.1 mrg
2225 1.1 mrg case FMT_DC:
2226 1.1 mrg consume_data_flag = 0;
2227 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_COMMA;
2228 1.1 mrg break;
2229 1.1 mrg
2230 1.1 mrg case FMT_DP:
2231 1.1 mrg consume_data_flag = 0;
2232 1.1 mrg dtp->u.p.current_unit->decimal_status = DECIMAL_POINT;
2233 1.1 mrg break;
2234 1.1 mrg
2235 1.1 mrg case FMT_RC:
2236 1.1 mrg consume_data_flag = 0;
2237 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_COMPATIBLE;
2238 1.1 mrg break;
2239 1.1 mrg
2240 1.1 mrg case FMT_RD:
2241 1.1 mrg consume_data_flag = 0;
2242 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_DOWN;
2243 1.1 mrg break;
2244 1.1 mrg
2245 1.1 mrg case FMT_RN:
2246 1.1 mrg consume_data_flag = 0;
2247 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_NEAREST;
2248 1.1 mrg break;
2249 1.1 mrg
2250 1.1 mrg case FMT_RP:
2251 1.1 mrg consume_data_flag = 0;
2252 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_PROCDEFINED;
2253 1.1 mrg break;
2254 1.1 mrg
2255 1.1 mrg case FMT_RU:
2256 1.1 mrg consume_data_flag = 0;
2257 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_UP;
2258 1.1 mrg break;
2259 1.1 mrg
2260 1.1 mrg case FMT_RZ:
2261 1.1 mrg consume_data_flag = 0;
2262 1.1 mrg dtp->u.p.current_unit->round_status = ROUND_ZERO;
2263 1.1 mrg break;
2264 1.1 mrg
2265 1.1 mrg case FMT_P:
2266 1.1 mrg consume_data_flag = 0;
2267 1.1 mrg dtp->u.p.scale_factor = f->u.k;
2268 1.1 mrg break;
2269 1.1 mrg
2270 1.1 mrg case FMT_DOLLAR:
2271 1.1 mrg consume_data_flag = 0;
2272 1.1 mrg dtp->u.p.seen_dollar = 1;
2273 1.1 mrg break;
2274 1.1 mrg
2275 1.1 mrg case FMT_SLASH:
2276 1.1 mrg consume_data_flag = 0;
2277 1.1 mrg dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
2278 1.1 mrg next_record (dtp, 0);
2279 1.1 mrg break;
2280 1.1 mrg
2281 1.1 mrg case FMT_COLON:
2282 1.1 mrg /* A colon descriptor causes us to exit this loop (in
2283 1.1 mrg particular preventing another / descriptor from being
2284 1.1 mrg processed) unless there is another data item to be
2285 1.1 mrg transferred. */
2286 1.1 mrg consume_data_flag = 0;
2287 1.1 mrg if (n == 0)
2288 1.1 mrg return;
2289 1.1 mrg break;
2290 1.1 mrg
2291 1.1 mrg default:
2292 1.1 mrg internal_error (&dtp->common, "Bad format node");
2293 1.1 mrg }
2294 1.1 mrg
2295 1.1 mrg /* Adjust the item count and data pointer. */
2296 1.1 mrg
2297 1.1 mrg if ((consume_data_flag > 0) && (n > 0))
2298 1.1 mrg {
2299 1.1 mrg n--;
2300 1.1 mrg p = ((char *) p) + size;
2301 1.1 mrg }
2302 1.1 mrg
2303 1.1 mrg pos = dtp->u.p.current_unit->recl - dtp->u.p.current_unit->bytes_left;
2304 1.1 mrg dtp->u.p.max_pos = (dtp->u.p.max_pos > pos) ? dtp->u.p.max_pos : pos;
2305 1.1 mrg }
2306 1.1 mrg
2307 1.1 mrg return;
2308 1.1 mrg
2309 1.1 mrg /* Come here when we need a data descriptor but don't have one. We
2310 1.1 mrg push the current format node back onto the input, then return and
2311 1.1 mrg let the user program call us back with the data. */
2312 1.1 mrg need_data:
2313 1.1 mrg unget_format (dtp, f);
2314 1.1 mrg }
2315 1.1 mrg
2316 1.1 mrg /* This function is first called from data_init_transfer to initiate the loop
2317 1.1 mrg over each item in the format, transferring data as required. Subsequent
2318 1.1 mrg calls to this function occur for each data item foound in the READ/WRITE
2319 1.1 mrg statement. The item_count is incremented for each call. Since the first
2320 1.1 mrg call is from data_transfer_init, the item_count is always one greater than
2321 1.1 mrg the actual count number of the item being transferred. */
2322 1.1 mrg
2323 1.1 mrg static void
2324 1.1 mrg formatted_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
2325 1.1 mrg size_t size, size_t nelems)
2326 1.1 mrg {
2327 1.1 mrg size_t elem;
2328 1.1 mrg char *tmp;
2329 1.1 mrg
2330 1.1 mrg tmp = (char *) p;
2331 1.1 mrg size_t stride = type == BT_CHARACTER ?
2332 1.1 mrg size * GFC_SIZE_OF_CHAR_KIND(kind) : size;
2333 1.1 mrg if (dtp->u.p.mode == READING)
2334 1.1 mrg {
2335 1.1 mrg /* Big loop over all the elements. */
2336 1.1 mrg for (elem = 0; elem < nelems; elem++)
2337 1.1 mrg {
2338 1.1 mrg dtp->u.p.item_count++;
2339 1.1 mrg formatted_transfer_scalar_read (dtp, type, tmp + stride*elem, kind, size);
2340 1.1 mrg }
2341 1.1 mrg }
2342 1.1 mrg else
2343 1.1 mrg {
2344 1.1 mrg /* Big loop over all the elements. */
2345 1.1 mrg for (elem = 0; elem < nelems; elem++)
2346 1.1 mrg {
2347 1.1 mrg dtp->u.p.item_count++;
2348 1.1 mrg formatted_transfer_scalar_write (dtp, type, tmp + stride*elem, kind, size);
2349 1.1 mrg }
2350 1.1 mrg }
2351 1.1 mrg }
2352 1.1 mrg
2353 1.1 mrg /* Wrapper function for I/O of scalar types. If this should be an async I/O
2354 1.1 mrg request, queue it. For a synchronous write on an async unit, perform the
2355 1.1 mrg wait operation and return an error. For all synchronous writes, call the
2356 1.1 mrg right transfer function. */
2357 1.1 mrg
2358 1.1 mrg static void
2359 1.1 mrg wrap_scalar_transfer (st_parameter_dt *dtp, bt type, void *p, int kind,
2360 1.1 mrg size_t size, size_t n_elem)
2361 1.1 mrg {
2362 1.1 mrg if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
2363 1.1 mrg {
2364 1.1 mrg if (dtp->u.p.async)
2365 1.1 mrg {
2366 1.1 mrg transfer_args args;
2367 1.1 mrg args.scalar.transfer = dtp->u.p.transfer;
2368 1.1 mrg args.scalar.arg_bt = type;
2369 1.1 mrg args.scalar.data = p;
2370 1.1 mrg args.scalar.i = kind;
2371 1.1 mrg args.scalar.s1 = size;
2372 1.1 mrg args.scalar.s2 = n_elem;
2373 1.1 mrg enqueue_transfer (dtp->u.p.current_unit->au, &args,
2374 1.1 mrg AIO_TRANSFER_SCALAR);
2375 1.1 mrg return;
2376 1.1 mrg }
2377 1.1 mrg }
2378 1.1 mrg /* Come here if there was no asynchronous I/O to be scheduled. */
2379 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2380 1.1 mrg return;
2381 1.1 mrg
2382 1.1 mrg dtp->u.p.transfer (dtp, type, p, kind, size, 1);
2383 1.1 mrg }
2384 1.1 mrg
2385 1.1 mrg
2386 1.1 mrg /* Data transfer entry points. The type of the data entity is
2387 1.1 mrg implicit in the subroutine call. This prevents us from having to
2388 1.1 mrg share a common enum with the compiler. */
2389 1.1 mrg
2390 1.1 mrg void
2391 1.1 mrg transfer_integer (st_parameter_dt *dtp, void *p, int kind)
2392 1.1 mrg {
2393 1.1 mrg wrap_scalar_transfer (dtp, BT_INTEGER, p, kind, kind, 1);
2394 1.1 mrg }
2395 1.1 mrg
2396 1.1 mrg void
2397 1.1 mrg transfer_integer_write (st_parameter_dt *dtp, void *p, int kind)
2398 1.1 mrg {
2399 1.1 mrg transfer_integer (dtp, p, kind);
2400 1.1 mrg }
2401 1.1 mrg
2402 1.1 mrg void
2403 1.1 mrg transfer_real (st_parameter_dt *dtp, void *p, int kind)
2404 1.1 mrg {
2405 1.1 mrg size_t size;
2406 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2407 1.1 mrg return;
2408 1.1 mrg size = size_from_real_kind (kind);
2409 1.1 mrg wrap_scalar_transfer (dtp, BT_REAL, p, kind, size, 1);
2410 1.1 mrg }
2411 1.1 mrg
2412 1.1 mrg void
2413 1.1 mrg transfer_real_write (st_parameter_dt *dtp, void *p, int kind)
2414 1.1 mrg {
2415 1.1 mrg transfer_real (dtp, p, kind);
2416 1.1 mrg }
2417 1.1 mrg
2418 1.1 mrg void
2419 1.1 mrg transfer_logical (st_parameter_dt *dtp, void *p, int kind)
2420 1.1 mrg {
2421 1.1 mrg wrap_scalar_transfer (dtp, BT_LOGICAL, p, kind, kind, 1);
2422 1.1 mrg }
2423 1.1 mrg
2424 1.1 mrg void
2425 1.1 mrg transfer_logical_write (st_parameter_dt *dtp, void *p, int kind)
2426 1.1 mrg {
2427 1.1 mrg transfer_logical (dtp, p, kind);
2428 1.1 mrg }
2429 1.1 mrg
2430 1.1 mrg void
2431 1.1 mrg transfer_character (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
2432 1.1 mrg {
2433 1.1 mrg static char *empty_string[0];
2434 1.1 mrg
2435 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2436 1.1 mrg return;
2437 1.1 mrg
2438 1.1 mrg /* Strings of zero length can have p == NULL, which confuses the
2439 1.1 mrg transfer routines into thinking we need more data elements. To avoid
2440 1.1 mrg this, we give them a nice pointer. */
2441 1.1 mrg if (len == 0 && p == NULL)
2442 1.1 mrg p = empty_string;
2443 1.1 mrg
2444 1.1 mrg /* Set kind here to 1. */
2445 1.1 mrg wrap_scalar_transfer (dtp, BT_CHARACTER, p, 1, len, 1);
2446 1.1 mrg }
2447 1.1 mrg
2448 1.1 mrg void
2449 1.1 mrg transfer_character_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len)
2450 1.1 mrg {
2451 1.1 mrg transfer_character (dtp, p, len);
2452 1.1 mrg }
2453 1.1 mrg
2454 1.1 mrg void
2455 1.1 mrg transfer_character_wide (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
2456 1.1 mrg {
2457 1.1 mrg static char *empty_string[0];
2458 1.1 mrg
2459 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2460 1.1 mrg return;
2461 1.1 mrg
2462 1.1 mrg /* Strings of zero length can have p == NULL, which confuses the
2463 1.1 mrg transfer routines into thinking we need more data elements. To avoid
2464 1.1 mrg this, we give them a nice pointer. */
2465 1.1 mrg if (len == 0 && p == NULL)
2466 1.1 mrg p = empty_string;
2467 1.1 mrg
2468 1.1 mrg /* Here we pass the actual kind value. */
2469 1.1 mrg wrap_scalar_transfer (dtp, BT_CHARACTER, p, kind, len, 1);
2470 1.1 mrg }
2471 1.1 mrg
2472 1.1 mrg void
2473 1.1 mrg transfer_character_wide_write (st_parameter_dt *dtp, void *p, gfc_charlen_type len, int kind)
2474 1.1 mrg {
2475 1.1 mrg transfer_character_wide (dtp, p, len, kind);
2476 1.1 mrg }
2477 1.1 mrg
2478 1.1 mrg void
2479 1.1 mrg transfer_complex (st_parameter_dt *dtp, void *p, int kind)
2480 1.1 mrg {
2481 1.1 mrg size_t size;
2482 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2483 1.1 mrg return;
2484 1.1 mrg size = size_from_complex_kind (kind);
2485 1.1 mrg wrap_scalar_transfer (dtp, BT_COMPLEX, p, kind, size, 1);
2486 1.1 mrg }
2487 1.1 mrg
2488 1.1 mrg void
2489 1.1 mrg transfer_complex_write (st_parameter_dt *dtp, void *p, int kind)
2490 1.1 mrg {
2491 1.1 mrg transfer_complex (dtp, p, kind);
2492 1.1 mrg }
2493 1.1 mrg
2494 1.1 mrg void
2495 1.1 mrg transfer_array_inner (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
2496 1.1 mrg gfc_charlen_type charlen)
2497 1.1 mrg {
2498 1.1 mrg index_type count[GFC_MAX_DIMENSIONS];
2499 1.1 mrg index_type extent[GFC_MAX_DIMENSIONS];
2500 1.1 mrg index_type stride[GFC_MAX_DIMENSIONS];
2501 1.1 mrg index_type stride0, rank, size, n;
2502 1.1 mrg size_t tsize;
2503 1.1 mrg char *data;
2504 1.1 mrg bt iotype;
2505 1.1 mrg
2506 1.1 mrg /* Adjust item_count before emitting error message. */
2507 1.1 mrg
2508 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2509 1.1 mrg return;
2510 1.1 mrg
2511 1.1 mrg iotype = (bt) GFC_DESCRIPTOR_TYPE (desc);
2512 1.1 mrg size = iotype == BT_CHARACTER ? charlen : GFC_DESCRIPTOR_SIZE (desc);
2513 1.1 mrg
2514 1.1 mrg rank = GFC_DESCRIPTOR_RANK (desc);
2515 1.1 mrg
2516 1.1 mrg for (n = 0; n < rank; n++)
2517 1.1 mrg {
2518 1.1 mrg count[n] = 0;
2519 1.1 mrg stride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(desc,n);
2520 1.1 mrg extent[n] = GFC_DESCRIPTOR_EXTENT(desc,n);
2521 1.1 mrg
2522 1.1 mrg /* If the extent of even one dimension is zero, then the entire
2523 1.1 mrg array section contains zero elements, so we return after writing
2524 1.1 mrg a zero array record. */
2525 1.1 mrg if (extent[n] <= 0)
2526 1.1 mrg {
2527 1.1 mrg data = NULL;
2528 1.1 mrg tsize = 0;
2529 1.1 mrg dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
2530 1.1 mrg return;
2531 1.1 mrg }
2532 1.1 mrg }
2533 1.1 mrg
2534 1.1 mrg stride0 = stride[0];
2535 1.1 mrg
2536 1.1 mrg /* If the innermost dimension has a stride of 1, we can do the transfer
2537 1.1 mrg in contiguous chunks. */
2538 1.1 mrg if (stride0 == size)
2539 1.1 mrg tsize = extent[0];
2540 1.1 mrg else
2541 1.1 mrg tsize = 1;
2542 1.1 mrg
2543 1.1 mrg data = GFC_DESCRIPTOR_DATA (desc);
2544 1.1 mrg
2545 1.1 mrg /* When reading, we need to check endfile conditions so we do not miss
2546 1.1 mrg an END=label. Make this separate so we do not have an extra test
2547 1.1 mrg in a tight loop when it is not needed. */
2548 1.1 mrg
2549 1.1 mrg if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
2550 1.1 mrg {
2551 1.1 mrg while (data)
2552 1.1 mrg {
2553 1.1 mrg if (unlikely (dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
2554 1.1 mrg return;
2555 1.1 mrg
2556 1.1 mrg dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
2557 1.1 mrg data += stride0 * tsize;
2558 1.1 mrg count[0] += tsize;
2559 1.1 mrg n = 0;
2560 1.1 mrg while (count[n] == extent[n])
2561 1.1 mrg {
2562 1.1 mrg count[n] = 0;
2563 1.1 mrg data -= stride[n] * extent[n];
2564 1.1 mrg n++;
2565 1.1 mrg if (n == rank)
2566 1.1 mrg {
2567 1.1 mrg data = NULL;
2568 1.1 mrg break;
2569 1.1 mrg }
2570 1.1 mrg else
2571 1.1 mrg {
2572 1.1 mrg count[n]++;
2573 1.1 mrg data += stride[n];
2574 1.1 mrg }
2575 1.1 mrg }
2576 1.1 mrg }
2577 1.1 mrg }
2578 1.1 mrg else
2579 1.1 mrg {
2580 1.1 mrg while (data)
2581 1.1 mrg {
2582 1.1 mrg dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
2583 1.1 mrg data += stride0 * tsize;
2584 1.1 mrg count[0] += tsize;
2585 1.1 mrg n = 0;
2586 1.1 mrg while (count[n] == extent[n])
2587 1.1 mrg {
2588 1.1 mrg count[n] = 0;
2589 1.1 mrg data -= stride[n] * extent[n];
2590 1.1 mrg n++;
2591 1.1 mrg if (n == rank)
2592 1.1 mrg {
2593 1.1 mrg data = NULL;
2594 1.1 mrg break;
2595 1.1 mrg }
2596 1.1 mrg else
2597 1.1 mrg {
2598 1.1 mrg count[n]++;
2599 1.1 mrg data += stride[n];
2600 1.1 mrg }
2601 1.1 mrg }
2602 1.1 mrg }
2603 1.1 mrg }
2604 1.1 mrg }
2605 1.1 mrg
2606 1.1 mrg void
2607 1.1 mrg transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
2608 1.1 mrg gfc_charlen_type charlen)
2609 1.1 mrg {
2610 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2611 1.1 mrg return;
2612 1.1 mrg
2613 1.1 mrg if (dtp->u.p.current_unit && dtp->u.p.current_unit->au)
2614 1.1 mrg {
2615 1.1 mrg if (dtp->u.p.async)
2616 1.1 mrg {
2617 1.1 mrg transfer_args args;
2618 1.1 mrg size_t sz = sizeof (gfc_array_char)
2619 1.1 mrg + sizeof (descriptor_dimension)
2620 1.1 mrg * GFC_DESCRIPTOR_RANK (desc);
2621 1.1 mrg args.array.desc = xmalloc (sz);
2622 1.1 mrg NOTE ("desc = %p", (void *) args.array.desc);
2623 1.1 mrg memcpy (args.array.desc, desc, sz);
2624 1.1 mrg args.array.kind = kind;
2625 1.1 mrg args.array.charlen = charlen;
2626 1.1 mrg enqueue_transfer (dtp->u.p.current_unit->au, &args,
2627 1.1 mrg AIO_TRANSFER_ARRAY);
2628 1.1 mrg return;
2629 1.1 mrg }
2630 1.1 mrg }
2631 1.1 mrg /* Come here if there was no asynchronous I/O to be scheduled. */
2632 1.1 mrg transfer_array_inner (dtp, desc, kind, charlen);
2633 1.1 mrg }
2634 1.1 mrg
2635 1.1 mrg
2636 1.1 mrg void
2637 1.1 mrg transfer_array_write (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
2638 1.1 mrg gfc_charlen_type charlen)
2639 1.1 mrg {
2640 1.1 mrg transfer_array (dtp, desc, kind, charlen);
2641 1.1 mrg }
2642 1.1 mrg
2643 1.1 mrg
2644 1.1 mrg /* User defined input/output iomsg. */
2645 1.1 mrg
2646 1.1 mrg #define IOMSG_LEN 256
2647 1.1 mrg
2648 1.1 mrg void
2649 1.1 mrg transfer_derived (st_parameter_dt *parent, void *dtio_source, void *dtio_proc)
2650 1.1 mrg {
2651 1.1 mrg if (parent->u.p.current_unit)
2652 1.1 mrg {
2653 1.1 mrg if (parent->u.p.current_unit->flags.form == FORM_UNFORMATTED)
2654 1.1 mrg parent->u.p.ufdtio_ptr = (unformatted_dtio) dtio_proc;
2655 1.1 mrg else
2656 1.1 mrg parent->u.p.fdtio_ptr = (formatted_dtio) dtio_proc;
2657 1.1 mrg }
2658 1.1 mrg wrap_scalar_transfer (parent, BT_CLASS, dtio_source, 0, 0, 1);
2659 1.1 mrg }
2660 1.1 mrg
2661 1.1 mrg
2662 1.1 mrg /* Preposition a sequential unformatted file while reading. */
2663 1.1 mrg
2664 1.1 mrg static void
2665 1.1 mrg us_read (st_parameter_dt *dtp, int continued)
2666 1.1 mrg {
2667 1.1 mrg ssize_t n, nr;
2668 1.1 mrg GFC_INTEGER_4 i4;
2669 1.1 mrg GFC_INTEGER_8 i8;
2670 1.1 mrg gfc_offset i;
2671 1.1 mrg
2672 1.1 mrg if (compile_options.record_marker == 0)
2673 1.1 mrg n = sizeof (GFC_INTEGER_4);
2674 1.1 mrg else
2675 1.1 mrg n = compile_options.record_marker;
2676 1.1 mrg
2677 1.1 mrg nr = sread (dtp->u.p.current_unit->s, &i, n);
2678 1.1 mrg if (unlikely (nr < 0))
2679 1.1 mrg {
2680 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
2681 1.1 mrg return;
2682 1.1 mrg }
2683 1.1 mrg else if (nr == 0)
2684 1.1 mrg {
2685 1.1 mrg hit_eof (dtp);
2686 1.1 mrg return; /* end of file */
2687 1.1 mrg }
2688 1.1 mrg else if (unlikely (n != nr))
2689 1.1 mrg {
2690 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
2691 1.1 mrg return;
2692 1.1 mrg }
2693 1.1 mrg
2694 1.1 mrg /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
2695 1.1 mrg if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
2696 1.1 mrg {
2697 1.1 mrg switch (nr)
2698 1.1 mrg {
2699 1.1 mrg case sizeof(GFC_INTEGER_4):
2700 1.1 mrg memcpy (&i4, &i, sizeof (i4));
2701 1.1 mrg i = i4;
2702 1.1 mrg break;
2703 1.1 mrg
2704 1.1 mrg case sizeof(GFC_INTEGER_8):
2705 1.1 mrg memcpy (&i8, &i, sizeof (i8));
2706 1.1 mrg i = i8;
2707 1.1 mrg break;
2708 1.1 mrg
2709 1.1 mrg default:
2710 1.1 mrg runtime_error ("Illegal value for record marker");
2711 1.1 mrg break;
2712 1.1 mrg }
2713 1.1 mrg }
2714 1.1 mrg else
2715 1.1 mrg {
2716 1.1 mrg uint32_t u32;
2717 1.1 mrg uint64_t u64;
2718 1.1 mrg switch (nr)
2719 1.1 mrg {
2720 1.1 mrg case sizeof(GFC_INTEGER_4):
2721 1.1 mrg memcpy (&u32, &i, sizeof (u32));
2722 1.1 mrg u32 = __builtin_bswap32 (u32);
2723 1.1 mrg memcpy (&i4, &u32, sizeof (i4));
2724 1.1 mrg i = i4;
2725 1.1 mrg break;
2726 1.1 mrg
2727 1.1 mrg case sizeof(GFC_INTEGER_8):
2728 1.1 mrg memcpy (&u64, &i, sizeof (u64));
2729 1.1 mrg u64 = __builtin_bswap64 (u64);
2730 1.1 mrg memcpy (&i8, &u64, sizeof (i8));
2731 1.1 mrg i = i8;
2732 1.1 mrg break;
2733 1.1 mrg
2734 1.1 mrg default:
2735 1.1 mrg runtime_error ("Illegal value for record marker");
2736 1.1 mrg break;
2737 1.1 mrg }
2738 1.1 mrg }
2739 1.1 mrg
2740 1.1 mrg if (i >= 0)
2741 1.1 mrg {
2742 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord = i;
2743 1.1 mrg dtp->u.p.current_unit->continued = 0;
2744 1.1 mrg }
2745 1.1 mrg else
2746 1.1 mrg {
2747 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord = -i;
2748 1.1 mrg dtp->u.p.current_unit->continued = 1;
2749 1.1 mrg }
2750 1.1 mrg
2751 1.1 mrg if (! continued)
2752 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2753 1.1 mrg }
2754 1.1 mrg
2755 1.1 mrg
2756 1.1 mrg /* Preposition a sequential unformatted file while writing. This
2757 1.1 mrg amount to writing a bogus length that will be filled in later. */
2758 1.1 mrg
2759 1.1 mrg static void
2760 1.1 mrg us_write (st_parameter_dt *dtp, int continued)
2761 1.1 mrg {
2762 1.1 mrg ssize_t nbytes;
2763 1.1 mrg gfc_offset dummy;
2764 1.1 mrg
2765 1.1 mrg dummy = 0;
2766 1.1 mrg
2767 1.1 mrg if (compile_options.record_marker == 0)
2768 1.1 mrg nbytes = sizeof (GFC_INTEGER_4);
2769 1.1 mrg else
2770 1.1 mrg nbytes = compile_options.record_marker ;
2771 1.1 mrg
2772 1.1 mrg if (swrite (dtp->u.p.current_unit->s, &dummy, nbytes) != nbytes)
2773 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
2774 1.1 mrg
2775 1.1 mrg /* For sequential unformatted, if RECL= was not specified in the OPEN
2776 1.1 mrg we write until we have more bytes than can fit in the subrecord
2777 1.1 mrg markers, then we write a new subrecord. */
2778 1.1 mrg
2779 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord =
2780 1.1 mrg dtp->u.p.current_unit->recl_subrecord;
2781 1.1 mrg dtp->u.p.current_unit->continued = continued;
2782 1.1 mrg }
2783 1.1 mrg
2784 1.1 mrg
2785 1.1 mrg /* Position to the next record prior to transfer. We are assumed to
2786 1.1 mrg be before the next record. We also calculate the bytes in the next
2787 1.1 mrg record. */
2788 1.1 mrg
2789 1.1 mrg static void
2790 1.1 mrg pre_position (st_parameter_dt *dtp)
2791 1.1 mrg {
2792 1.1 mrg if (dtp->u.p.current_unit->current_record)
2793 1.1 mrg return; /* Already positioned. */
2794 1.1 mrg
2795 1.1 mrg switch (current_mode (dtp))
2796 1.1 mrg {
2797 1.1 mrg case FORMATTED_STREAM:
2798 1.1 mrg case UNFORMATTED_STREAM:
2799 1.1 mrg /* There are no records with stream I/O. If the position was specified
2800 1.1 mrg data_transfer_init has already positioned the file. If no position
2801 1.1 mrg was specified, we continue from where we last left off. I.e.
2802 1.1 mrg there is nothing to do here. */
2803 1.1 mrg break;
2804 1.1 mrg
2805 1.1 mrg case UNFORMATTED_SEQUENTIAL:
2806 1.1 mrg if (dtp->u.p.mode == READING)
2807 1.1 mrg us_read (dtp, 0);
2808 1.1 mrg else
2809 1.1 mrg us_write (dtp, 0);
2810 1.1 mrg
2811 1.1 mrg break;
2812 1.1 mrg
2813 1.1 mrg case FORMATTED_SEQUENTIAL:
2814 1.1 mrg case FORMATTED_DIRECT:
2815 1.1 mrg case UNFORMATTED_DIRECT:
2816 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
2817 1.1 mrg break;
2818 1.1.1.2 mrg case FORMATTED_UNSPECIFIED:
2819 1.1.1.2 mrg gcc_unreachable ();
2820 1.1 mrg }
2821 1.1 mrg
2822 1.1 mrg dtp->u.p.current_unit->current_record = 1;
2823 1.1 mrg }
2824 1.1 mrg
2825 1.1 mrg
2826 1.1 mrg /* Initialize things for a data transfer. This code is common for
2827 1.1 mrg both reading and writing. */
2828 1.1 mrg
2829 1.1 mrg static void
2830 1.1 mrg data_transfer_init (st_parameter_dt *dtp, int read_flag)
2831 1.1 mrg {
2832 1.1 mrg unit_flags u_flags; /* Used for creating a unit if needed. */
2833 1.1 mrg GFC_INTEGER_4 cf = dtp->common.flags;
2834 1.1 mrg namelist_info *ionml;
2835 1.1 mrg async_unit *au;
2836 1.1 mrg
2837 1.1 mrg NOTE ("data_transfer_init");
2838 1.1 mrg
2839 1.1 mrg ionml = ((cf & IOPARM_DT_IONML_SET) != 0) ? dtp->u.p.ionml : NULL;
2840 1.1 mrg
2841 1.1 mrg memset (&dtp->u.p, 0, sizeof (dtp->u.p));
2842 1.1 mrg
2843 1.1 mrg dtp->u.p.ionml = ionml;
2844 1.1 mrg dtp->u.p.mode = read_flag ? READING : WRITING;
2845 1.1 mrg dtp->u.p.namelist_mode = 0;
2846 1.1 mrg dtp->u.p.cc.len = 0;
2847 1.1 mrg
2848 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
2849 1.1 mrg return;
2850 1.1 mrg
2851 1.1 mrg dtp->u.p.current_unit = get_unit (dtp, 1);
2852 1.1 mrg
2853 1.1 mrg if (dtp->u.p.current_unit == NULL)
2854 1.1 mrg {
2855 1.1 mrg /* This means we tried to access an external unit < 0 without
2856 1.1 mrg having opened it first with NEWUNIT=. */
2857 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
2858 1.1 mrg "Unit number is negative and unit was not already "
2859 1.1 mrg "opened with OPEN(NEWUNIT=...)");
2860 1.1 mrg return;
2861 1.1 mrg }
2862 1.1 mrg else if (dtp->u.p.current_unit->s == NULL)
2863 1.1 mrg { /* Open the unit with some default flags. */
2864 1.1 mrg st_parameter_open opp;
2865 1.1 mrg unit_convert conv;
2866 1.1 mrg NOTE ("Open the unit with some default flags.");
2867 1.1 mrg memset (&u_flags, '\0', sizeof (u_flags));
2868 1.1 mrg u_flags.access = ACCESS_SEQUENTIAL;
2869 1.1 mrg u_flags.action = ACTION_READWRITE;
2870 1.1 mrg
2871 1.1 mrg /* Is it unformatted? */
2872 1.1 mrg if (!(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT
2873 1.1 mrg | IOPARM_DT_IONML_SET)))
2874 1.1 mrg u_flags.form = FORM_UNFORMATTED;
2875 1.1 mrg else
2876 1.1 mrg u_flags.form = FORM_UNSPECIFIED;
2877 1.1 mrg
2878 1.1 mrg u_flags.delim = DELIM_UNSPECIFIED;
2879 1.1 mrg u_flags.blank = BLANK_UNSPECIFIED;
2880 1.1 mrg u_flags.pad = PAD_UNSPECIFIED;
2881 1.1 mrg u_flags.decimal = DECIMAL_UNSPECIFIED;
2882 1.1 mrg u_flags.encoding = ENCODING_UNSPECIFIED;
2883 1.1 mrg u_flags.async = ASYNC_UNSPECIFIED;
2884 1.1 mrg u_flags.round = ROUND_UNSPECIFIED;
2885 1.1 mrg u_flags.sign = SIGN_UNSPECIFIED;
2886 1.1 mrg u_flags.share = SHARE_UNSPECIFIED;
2887 1.1 mrg u_flags.cc = CC_UNSPECIFIED;
2888 1.1 mrg u_flags.readonly = 0;
2889 1.1 mrg
2890 1.1 mrg u_flags.status = STATUS_UNKNOWN;
2891 1.1 mrg
2892 1.1 mrg conv = get_unformatted_convert (dtp->common.unit);
2893 1.1 mrg
2894 1.1 mrg if (conv == GFC_CONVERT_NONE)
2895 1.1 mrg conv = compile_options.convert;
2896 1.1 mrg
2897 1.1 mrg switch (conv)
2898 1.1 mrg {
2899 1.1 mrg case GFC_CONVERT_NATIVE:
2900 1.1 mrg case GFC_CONVERT_SWAP:
2901 1.1 mrg break;
2902 1.1 mrg
2903 1.1 mrg case GFC_CONVERT_BIG:
2904 1.1 mrg conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_NATIVE : GFC_CONVERT_SWAP;
2905 1.1 mrg break;
2906 1.1 mrg
2907 1.1 mrg case GFC_CONVERT_LITTLE:
2908 1.1 mrg conv = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? GFC_CONVERT_SWAP : GFC_CONVERT_NATIVE;
2909 1.1 mrg break;
2910 1.1 mrg
2911 1.1 mrg default:
2912 1.1 mrg internal_error (&opp.common, "Illegal value for CONVERT");
2913 1.1 mrg break;
2914 1.1 mrg }
2915 1.1 mrg
2916 1.1 mrg u_flags.convert = conv;
2917 1.1 mrg
2918 1.1 mrg opp.common = dtp->common;
2919 1.1 mrg opp.common.flags &= IOPARM_COMMON_MASK;
2920 1.1 mrg dtp->u.p.current_unit = new_unit (&opp, dtp->u.p.current_unit, &u_flags);
2921 1.1 mrg dtp->common.flags &= ~IOPARM_COMMON_MASK;
2922 1.1 mrg dtp->common.flags |= (opp.common.flags & IOPARM_COMMON_MASK);
2923 1.1 mrg if (dtp->u.p.current_unit == NULL)
2924 1.1 mrg return;
2925 1.1 mrg }
2926 1.1 mrg
2927 1.1 mrg if (dtp->u.p.current_unit->child_dtio == 0)
2928 1.1 mrg {
2929 1.1 mrg if ((cf & IOPARM_DT_HAS_SIZE) != 0)
2930 1.1 mrg {
2931 1.1 mrg dtp->u.p.current_unit->has_size = true;
2932 1.1 mrg /* Initialize the count. */
2933 1.1 mrg dtp->u.p.current_unit->size_used = 0;
2934 1.1 mrg }
2935 1.1 mrg else
2936 1.1 mrg dtp->u.p.current_unit->has_size = false;
2937 1.1 mrg }
2938 1.1 mrg else if (dtp->u.p.current_unit->internal_unit_kind > 0)
2939 1.1 mrg dtp->u.p.unit_is_internal = 1;
2940 1.1 mrg
2941 1.1 mrg if ((cf & IOPARM_DT_HAS_ASYNCHRONOUS) != 0)
2942 1.1 mrg {
2943 1.1 mrg int f;
2944 1.1 mrg f = find_option (&dtp->common, dtp->asynchronous, dtp->asynchronous_len,
2945 1.1 mrg async_opt, "Bad ASYNCHRONOUS in data transfer "
2946 1.1 mrg "statement");
2947 1.1 mrg if (f == ASYNC_YES && dtp->u.p.current_unit->flags.async != ASYNC_YES)
2948 1.1 mrg {
2949 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
2950 1.1 mrg "ASYNCHRONOUS transfer without "
2951 1.1 mrg "ASYHCRONOUS='YES' in OPEN");
2952 1.1 mrg return;
2953 1.1 mrg }
2954 1.1 mrg dtp->u.p.async = f == ASYNC_YES;
2955 1.1 mrg }
2956 1.1 mrg
2957 1.1 mrg au = dtp->u.p.current_unit->au;
2958 1.1 mrg if (au)
2959 1.1 mrg {
2960 1.1 mrg if (dtp->u.p.async)
2961 1.1 mrg {
2962 1.1 mrg /* If this is an asynchronous I/O statement, collect errors and
2963 1.1 mrg return if there are any. */
2964 1.1 mrg if (collect_async_errors (&dtp->common, au))
2965 1.1 mrg return;
2966 1.1 mrg }
2967 1.1 mrg else
2968 1.1 mrg {
2969 1.1 mrg /* Synchronous statement: Perform a wait operation for any pending
2970 1.1 mrg asynchronous I/O. This needs to be done before all other error
2971 1.1 mrg checks. See F2008, 9.6.4.1. */
2972 1.1 mrg if (async_wait (&(dtp->common), au))
2973 1.1 mrg return;
2974 1.1 mrg }
2975 1.1 mrg }
2976 1.1 mrg
2977 1.1 mrg /* Check the action. */
2978 1.1 mrg
2979 1.1 mrg if (read_flag && dtp->u.p.current_unit->flags.action == ACTION_WRITE)
2980 1.1 mrg {
2981 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_ACTION,
2982 1.1 mrg "Cannot read from file opened for WRITE");
2983 1.1 mrg return;
2984 1.1 mrg }
2985 1.1 mrg
2986 1.1 mrg if (!read_flag && dtp->u.p.current_unit->flags.action == ACTION_READ)
2987 1.1 mrg {
2988 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_ACTION,
2989 1.1 mrg "Cannot write to file opened for READ");
2990 1.1 mrg return;
2991 1.1 mrg }
2992 1.1 mrg
2993 1.1 mrg dtp->u.p.first_item = 1;
2994 1.1 mrg
2995 1.1 mrg /* Check the format. */
2996 1.1 mrg
2997 1.1 mrg if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
2998 1.1 mrg parse_format (dtp);
2999 1.1 mrg
3000 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED
3001 1.1 mrg && (cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
3002 1.1 mrg != 0)
3003 1.1 mrg {
3004 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3005 1.1 mrg "Format present for UNFORMATTED data transfer");
3006 1.1 mrg return;
3007 1.1 mrg }
3008 1.1 mrg
3009 1.1 mrg if ((cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0 && dtp->u.p.ionml != NULL)
3010 1.1 mrg {
3011 1.1 mrg if ((cf & IOPARM_DT_HAS_FORMAT) != 0)
3012 1.1 mrg {
3013 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3014 1.1 mrg "A format cannot be specified with a namelist");
3015 1.1 mrg return;
3016 1.1 mrg }
3017 1.1 mrg }
3018 1.1 mrg else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED &&
3019 1.1 mrg !(cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT)))
3020 1.1 mrg {
3021 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3022 1.1 mrg "Missing format for FORMATTED data transfer");
3023 1.1 mrg return;
3024 1.1 mrg }
3025 1.1 mrg
3026 1.1 mrg if (is_internal_unit (dtp)
3027 1.1 mrg && dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
3028 1.1 mrg {
3029 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3030 1.1 mrg "Internal file cannot be accessed by UNFORMATTED "
3031 1.1 mrg "data transfer");
3032 1.1 mrg return;
3033 1.1 mrg }
3034 1.1 mrg
3035 1.1 mrg /* Check the record or position number. */
3036 1.1 mrg
3037 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT
3038 1.1 mrg && (cf & IOPARM_DT_HAS_REC) == 0)
3039 1.1 mrg {
3040 1.1 mrg generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
3041 1.1 mrg "Direct access data transfer requires record number");
3042 1.1 mrg return;
3043 1.1 mrg }
3044 1.1 mrg
3045 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
3046 1.1 mrg {
3047 1.1 mrg if ((cf & IOPARM_DT_HAS_REC) != 0)
3048 1.1 mrg {
3049 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3050 1.1 mrg "Record number not allowed for sequential access "
3051 1.1 mrg "data transfer");
3052 1.1 mrg return;
3053 1.1 mrg }
3054 1.1 mrg
3055 1.1 mrg if (compile_options.warn_std &&
3056 1.1 mrg dtp->u.p.current_unit->endfile == AFTER_ENDFILE)
3057 1.1 mrg {
3058 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3059 1.1 mrg "Sequential READ or WRITE not allowed after "
3060 1.1 mrg "EOF marker, possibly use REWIND or BACKSPACE");
3061 1.1 mrg return;
3062 1.1 mrg }
3063 1.1 mrg }
3064 1.1 mrg
3065 1.1 mrg /* Process the ADVANCE option. */
3066 1.1 mrg
3067 1.1 mrg dtp->u.p.advance_status
3068 1.1 mrg = !(cf & IOPARM_DT_HAS_ADVANCE) ? ADVANCE_UNSPECIFIED :
3069 1.1 mrg find_option (&dtp->common, dtp->advance, dtp->advance_len, advance_opt,
3070 1.1 mrg "Bad ADVANCE parameter in data transfer statement");
3071 1.1 mrg
3072 1.1 mrg if (dtp->u.p.advance_status != ADVANCE_UNSPECIFIED)
3073 1.1 mrg {
3074 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
3075 1.1 mrg {
3076 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3077 1.1 mrg "ADVANCE specification conflicts with sequential "
3078 1.1 mrg "access");
3079 1.1 mrg return;
3080 1.1 mrg }
3081 1.1 mrg
3082 1.1 mrg if (is_internal_unit (dtp))
3083 1.1 mrg {
3084 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3085 1.1 mrg "ADVANCE specification conflicts with internal file");
3086 1.1 mrg return;
3087 1.1 mrg }
3088 1.1 mrg
3089 1.1 mrg if ((cf & (IOPARM_DT_HAS_FORMAT | IOPARM_DT_LIST_FORMAT))
3090 1.1 mrg != IOPARM_DT_HAS_FORMAT)
3091 1.1 mrg {
3092 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3093 1.1 mrg "ADVANCE specification requires an explicit format");
3094 1.1 mrg return;
3095 1.1 mrg }
3096 1.1 mrg }
3097 1.1 mrg
3098 1.1 mrg /* Child IO is non-advancing and any ADVANCE= specifier is ignored.
3099 1.1 mrg F2008 9.6.2.4 */
3100 1.1 mrg if (dtp->u.p.current_unit->child_dtio > 0)
3101 1.1 mrg dtp->u.p.advance_status = ADVANCE_NO;
3102 1.1 mrg
3103 1.1 mrg if (read_flag)
3104 1.1 mrg {
3105 1.1 mrg dtp->u.p.current_unit->previous_nonadvancing_write = 0;
3106 1.1 mrg
3107 1.1 mrg if ((cf & IOPARM_EOR) != 0 && dtp->u.p.advance_status != ADVANCE_NO)
3108 1.1 mrg {
3109 1.1 mrg generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
3110 1.1 mrg "EOR specification requires an ADVANCE specification "
3111 1.1 mrg "of NO");
3112 1.1 mrg return;
3113 1.1 mrg }
3114 1.1 mrg
3115 1.1 mrg if ((cf & IOPARM_DT_HAS_SIZE) != 0
3116 1.1 mrg && dtp->u.p.advance_status != ADVANCE_NO)
3117 1.1 mrg {
3118 1.1 mrg generate_error (&dtp->common, LIBERROR_MISSING_OPTION,
3119 1.1 mrg "SIZE specification requires an ADVANCE "
3120 1.1 mrg "specification of NO");
3121 1.1 mrg return;
3122 1.1 mrg }
3123 1.1 mrg }
3124 1.1 mrg else
3125 1.1 mrg { /* Write constraints. */
3126 1.1 mrg if ((cf & IOPARM_END) != 0)
3127 1.1 mrg {
3128 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3129 1.1 mrg "END specification cannot appear in a write "
3130 1.1 mrg "statement");
3131 1.1 mrg return;
3132 1.1 mrg }
3133 1.1 mrg
3134 1.1 mrg if ((cf & IOPARM_EOR) != 0)
3135 1.1 mrg {
3136 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3137 1.1 mrg "EOR specification cannot appear in a write "
3138 1.1 mrg "statement");
3139 1.1 mrg return;
3140 1.1 mrg }
3141 1.1 mrg
3142 1.1 mrg if ((cf & IOPARM_DT_HAS_SIZE) != 0)
3143 1.1 mrg {
3144 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3145 1.1 mrg "SIZE specification cannot appear in a write "
3146 1.1 mrg "statement");
3147 1.1 mrg return;
3148 1.1 mrg }
3149 1.1 mrg }
3150 1.1 mrg
3151 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_UNSPECIFIED)
3152 1.1 mrg dtp->u.p.advance_status = ADVANCE_YES;
3153 1.1 mrg
3154 1.1 mrg /* Check the decimal mode. */
3155 1.1 mrg dtp->u.p.current_unit->decimal_status
3156 1.1 mrg = !(cf & IOPARM_DT_HAS_DECIMAL) ? DECIMAL_UNSPECIFIED :
3157 1.1 mrg find_option (&dtp->common, dtp->decimal, dtp->decimal_len,
3158 1.1 mrg decimal_opt, "Bad DECIMAL parameter in data transfer "
3159 1.1 mrg "statement");
3160 1.1 mrg
3161 1.1 mrg if (dtp->u.p.current_unit->decimal_status == DECIMAL_UNSPECIFIED)
3162 1.1 mrg dtp->u.p.current_unit->decimal_status = dtp->u.p.current_unit->flags.decimal;
3163 1.1 mrg
3164 1.1 mrg /* Check the round mode. */
3165 1.1 mrg dtp->u.p.current_unit->round_status
3166 1.1 mrg = !(cf & IOPARM_DT_HAS_ROUND) ? ROUND_UNSPECIFIED :
3167 1.1 mrg find_option (&dtp->common, dtp->round, dtp->round_len,
3168 1.1 mrg round_opt, "Bad ROUND parameter in data transfer "
3169 1.1 mrg "statement");
3170 1.1 mrg
3171 1.1 mrg if (dtp->u.p.current_unit->round_status == ROUND_UNSPECIFIED)
3172 1.1 mrg dtp->u.p.current_unit->round_status = dtp->u.p.current_unit->flags.round;
3173 1.1 mrg
3174 1.1 mrg /* Check the sign mode. */
3175 1.1 mrg dtp->u.p.sign_status
3176 1.1 mrg = !(cf & IOPARM_DT_HAS_SIGN) ? SIGN_UNSPECIFIED :
3177 1.1 mrg find_option (&dtp->common, dtp->sign, dtp->sign_len, sign_opt,
3178 1.1 mrg "Bad SIGN parameter in data transfer statement");
3179 1.1 mrg
3180 1.1 mrg if (dtp->u.p.sign_status == SIGN_UNSPECIFIED)
3181 1.1 mrg dtp->u.p.sign_status = dtp->u.p.current_unit->flags.sign;
3182 1.1 mrg
3183 1.1 mrg /* Check the blank mode. */
3184 1.1 mrg dtp->u.p.blank_status
3185 1.1 mrg = !(cf & IOPARM_DT_HAS_BLANK) ? BLANK_UNSPECIFIED :
3186 1.1 mrg find_option (&dtp->common, dtp->blank, dtp->blank_len,
3187 1.1 mrg blank_opt,
3188 1.1 mrg "Bad BLANK parameter in data transfer statement");
3189 1.1 mrg
3190 1.1 mrg if (dtp->u.p.blank_status == BLANK_UNSPECIFIED)
3191 1.1 mrg dtp->u.p.blank_status = dtp->u.p.current_unit->flags.blank;
3192 1.1 mrg
3193 1.1 mrg /* Check the delim mode. */
3194 1.1 mrg dtp->u.p.current_unit->delim_status
3195 1.1 mrg = !(cf & IOPARM_DT_HAS_DELIM) ? DELIM_UNSPECIFIED :
3196 1.1 mrg find_option (&dtp->common, dtp->delim, dtp->delim_len,
3197 1.1 mrg delim_opt, "Bad DELIM parameter in data transfer statement");
3198 1.1 mrg
3199 1.1 mrg if (dtp->u.p.current_unit->delim_status == DELIM_UNSPECIFIED)
3200 1.1 mrg {
3201 1.1 mrg if (ionml && dtp->u.p.current_unit->flags.delim == DELIM_UNSPECIFIED)
3202 1.1 mrg dtp->u.p.current_unit->delim_status = DELIM_QUOTE;
3203 1.1 mrg else
3204 1.1 mrg dtp->u.p.current_unit->delim_status = dtp->u.p.current_unit->flags.delim;
3205 1.1 mrg }
3206 1.1 mrg
3207 1.1 mrg /* Check the pad mode. */
3208 1.1 mrg dtp->u.p.current_unit->pad_status
3209 1.1 mrg = !(cf & IOPARM_DT_HAS_PAD) ? PAD_UNSPECIFIED :
3210 1.1 mrg find_option (&dtp->common, dtp->pad, dtp->pad_len, pad_opt,
3211 1.1 mrg "Bad PAD parameter in data transfer statement");
3212 1.1 mrg
3213 1.1 mrg if (dtp->u.p.current_unit->pad_status == PAD_UNSPECIFIED)
3214 1.1 mrg dtp->u.p.current_unit->pad_status = dtp->u.p.current_unit->flags.pad;
3215 1.1 mrg
3216 1.1 mrg /* Set up the subroutine that will handle the transfers. */
3217 1.1 mrg
3218 1.1 mrg if (read_flag)
3219 1.1 mrg {
3220 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
3221 1.1 mrg dtp->u.p.transfer = unformatted_read;
3222 1.1 mrg else
3223 1.1 mrg {
3224 1.1 mrg if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
3225 1.1 mrg dtp->u.p.transfer = list_formatted_read;
3226 1.1 mrg else
3227 1.1 mrg dtp->u.p.transfer = formatted_transfer;
3228 1.1 mrg }
3229 1.1 mrg }
3230 1.1 mrg else
3231 1.1 mrg {
3232 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_UNFORMATTED)
3233 1.1 mrg dtp->u.p.transfer = unformatted_write;
3234 1.1 mrg else
3235 1.1 mrg {
3236 1.1 mrg if ((cf & IOPARM_DT_LIST_FORMAT) != 0)
3237 1.1 mrg dtp->u.p.transfer = list_formatted_write;
3238 1.1 mrg else
3239 1.1 mrg dtp->u.p.transfer = formatted_transfer;
3240 1.1 mrg }
3241 1.1 mrg }
3242 1.1 mrg
3243 1.1 mrg if (au && dtp->u.p.async)
3244 1.1 mrg {
3245 1.1 mrg NOTE ("enqueue_data_transfer");
3246 1.1 mrg enqueue_data_transfer_init (au, dtp, read_flag);
3247 1.1 mrg }
3248 1.1 mrg else
3249 1.1 mrg {
3250 1.1 mrg NOTE ("invoking data_transfer_init_worker");
3251 1.1 mrg data_transfer_init_worker (dtp, read_flag);
3252 1.1 mrg }
3253 1.1 mrg }
3254 1.1 mrg
3255 1.1 mrg void
3256 1.1 mrg data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
3257 1.1 mrg {
3258 1.1 mrg GFC_INTEGER_4 cf = dtp->common.flags;
3259 1.1 mrg
3260 1.1 mrg NOTE ("starting worker...");
3261 1.1 mrg
3262 1.1 mrg if (read_flag && dtp->u.p.current_unit->flags.form != FORM_UNFORMATTED
3263 1.1 mrg && ((cf & IOPARM_DT_LIST_FORMAT) != 0)
3264 1.1 mrg && dtp->u.p.current_unit->child_dtio == 0)
3265 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
3266 1.1 mrg
3267 1.1 mrg /* Check to see if we might be reading what we wrote before */
3268 1.1 mrg
3269 1.1 mrg if (dtp->u.p.mode != dtp->u.p.current_unit->mode
3270 1.1 mrg && !is_internal_unit (dtp))
3271 1.1 mrg {
3272 1.1 mrg int pos = fbuf_reset (dtp->u.p.current_unit);
3273 1.1 mrg if (pos != 0)
3274 1.1 mrg sseek (dtp->u.p.current_unit->s, pos, SEEK_CUR);
3275 1.1 mrg sflush(dtp->u.p.current_unit->s);
3276 1.1 mrg }
3277 1.1 mrg
3278 1.1 mrg /* Check the POS= specifier: that it is in range and that it is used with a
3279 1.1 mrg unit that has been connected for STREAM access. F2003 9.5.1.10. */
3280 1.1 mrg
3281 1.1 mrg if (((cf & IOPARM_DT_HAS_POS) != 0))
3282 1.1 mrg {
3283 1.1 mrg if (is_stream_io (dtp))
3284 1.1 mrg {
3285 1.1 mrg
3286 1.1 mrg if (dtp->pos <= 0)
3287 1.1 mrg {
3288 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3289 1.1 mrg "POS=specifier must be positive");
3290 1.1 mrg return;
3291 1.1 mrg }
3292 1.1 mrg
3293 1.1 mrg if (dtp->pos >= dtp->u.p.current_unit->maxrec)
3294 1.1 mrg {
3295 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3296 1.1 mrg "POS=specifier too large");
3297 1.1 mrg return;
3298 1.1 mrg }
3299 1.1 mrg
3300 1.1 mrg dtp->rec = dtp->pos;
3301 1.1 mrg
3302 1.1 mrg if (dtp->u.p.mode == READING)
3303 1.1 mrg {
3304 1.1 mrg /* Reset the endfile flag; if we hit EOF during reading
3305 1.1 mrg we'll set the flag and generate an error at that point
3306 1.1 mrg rather than worrying about it here. */
3307 1.1 mrg dtp->u.p.current_unit->endfile = NO_ENDFILE;
3308 1.1 mrg }
3309 1.1 mrg
3310 1.1 mrg if (dtp->pos != dtp->u.p.current_unit->strm_pos)
3311 1.1 mrg {
3312 1.1.1.2 mrg fbuf_reset (dtp->u.p.current_unit);
3313 1.1.1.2 mrg if (sseek (dtp->u.p.current_unit->s, dtp->pos - 1,
3314 1.1.1.2 mrg SEEK_SET) < 0)
3315 1.1 mrg {
3316 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3317 1.1 mrg return;
3318 1.1 mrg }
3319 1.1 mrg dtp->u.p.current_unit->strm_pos = dtp->pos;
3320 1.1 mrg }
3321 1.1 mrg }
3322 1.1 mrg else
3323 1.1 mrg {
3324 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3325 1.1 mrg "POS=specifier not allowed, "
3326 1.1 mrg "Try OPEN with ACCESS='stream'");
3327 1.1 mrg return;
3328 1.1 mrg }
3329 1.1 mrg }
3330 1.1 mrg
3331 1.1 mrg
3332 1.1 mrg /* Sanity checks on the record number. */
3333 1.1 mrg if ((cf & IOPARM_DT_HAS_REC) != 0)
3334 1.1 mrg {
3335 1.1 mrg if (dtp->rec <= 0)
3336 1.1 mrg {
3337 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3338 1.1 mrg "Record number must be positive");
3339 1.1 mrg return;
3340 1.1 mrg }
3341 1.1 mrg
3342 1.1 mrg if (dtp->rec >= dtp->u.p.current_unit->maxrec)
3343 1.1 mrg {
3344 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3345 1.1 mrg "Record number too large");
3346 1.1 mrg return;
3347 1.1 mrg }
3348 1.1 mrg
3349 1.1 mrg /* Make sure format buffer is reset. */
3350 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
3351 1.1 mrg fbuf_reset (dtp->u.p.current_unit);
3352 1.1 mrg
3353 1.1 mrg
3354 1.1 mrg /* Check whether the record exists to be read. Only
3355 1.1 mrg a partial record needs to exist. */
3356 1.1 mrg
3357 1.1 mrg if (dtp->u.p.mode == READING && (dtp->rec - 1)
3358 1.1 mrg * dtp->u.p.current_unit->recl >= ssize (dtp->u.p.current_unit->s))
3359 1.1 mrg {
3360 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3361 1.1 mrg "Non-existing record number");
3362 1.1 mrg return;
3363 1.1 mrg }
3364 1.1 mrg
3365 1.1 mrg /* Position the file. */
3366 1.1 mrg if (sseek (dtp->u.p.current_unit->s, (gfc_offset) (dtp->rec - 1)
3367 1.1 mrg * dtp->u.p.current_unit->recl, SEEK_SET) < 0)
3368 1.1 mrg {
3369 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3370 1.1 mrg return;
3371 1.1 mrg }
3372 1.1 mrg
3373 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
3374 1.1 mrg {
3375 1.1 mrg generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
3376 1.1 mrg "Record number not allowed for stream access "
3377 1.1 mrg "data transfer");
3378 1.1 mrg return;
3379 1.1 mrg }
3380 1.1 mrg }
3381 1.1 mrg
3382 1.1 mrg /* Bugware for badly written mixed C-Fortran I/O. */
3383 1.1 mrg if (!is_internal_unit (dtp))
3384 1.1 mrg flush_if_preconnected(dtp->u.p.current_unit->s);
3385 1.1 mrg
3386 1.1 mrg dtp->u.p.current_unit->mode = dtp->u.p.mode;
3387 1.1 mrg
3388 1.1 mrg /* Set the maximum position reached from the previous I/O operation. This
3389 1.1 mrg could be greater than zero from a previous non-advancing write. */
3390 1.1 mrg dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
3391 1.1 mrg
3392 1.1 mrg pre_position (dtp);
3393 1.1 mrg
3394 1.1 mrg /* Make sure that we don't do a read after a nonadvancing write. */
3395 1.1 mrg
3396 1.1 mrg if (read_flag)
3397 1.1 mrg {
3398 1.1 mrg if (dtp->u.p.current_unit->read_bad && !is_stream_io (dtp))
3399 1.1 mrg {
3400 1.1 mrg generate_error (&dtp->common, LIBERROR_BAD_OPTION,
3401 1.1 mrg "Cannot READ after a nonadvancing WRITE");
3402 1.1 mrg return;
3403 1.1 mrg }
3404 1.1 mrg }
3405 1.1 mrg else
3406 1.1 mrg {
3407 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_YES && !dtp->u.p.seen_dollar)
3408 1.1 mrg dtp->u.p.current_unit->read_bad = 1;
3409 1.1 mrg }
3410 1.1 mrg
3411 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
3412 1.1 mrg {
3413 1.1 mrg #ifdef HAVE_USELOCALE
3414 1.1 mrg dtp->u.p.old_locale = uselocale (c_locale);
3415 1.1 mrg #else
3416 1.1 mrg __gthread_mutex_lock (&old_locale_lock);
3417 1.1 mrg if (!old_locale_ctr++)
3418 1.1 mrg {
3419 1.1 mrg old_locale = setlocale (LC_NUMERIC, NULL);
3420 1.1 mrg setlocale (LC_NUMERIC, "C");
3421 1.1 mrg }
3422 1.1 mrg __gthread_mutex_unlock (&old_locale_lock);
3423 1.1 mrg #endif
3424 1.1 mrg /* Start the data transfer if we are doing a formatted transfer. */
3425 1.1 mrg if ((cf & (IOPARM_DT_LIST_FORMAT | IOPARM_DT_HAS_NAMELIST_NAME)) == 0
3426 1.1 mrg && dtp->u.p.ionml == NULL)
3427 1.1 mrg formatted_transfer (dtp, 0, NULL, 0, 0, 1);
3428 1.1 mrg }
3429 1.1 mrg }
3430 1.1 mrg
3431 1.1 mrg
3432 1.1 mrg /* Initialize an array_loop_spec given the array descriptor. The function
3433 1.1 mrg returns the index of the last element of the array, and also returns
3434 1.1 mrg starting record, where the first I/O goes to (necessary in case of
3435 1.1 mrg negative strides). */
3436 1.1 mrg
3437 1.1 mrg gfc_offset
3438 1.1 mrg init_loop_spec (gfc_array_char *desc, array_loop_spec *ls,
3439 1.1 mrg gfc_offset *start_record)
3440 1.1 mrg {
3441 1.1 mrg int rank = GFC_DESCRIPTOR_RANK(desc);
3442 1.1 mrg int i;
3443 1.1 mrg gfc_offset index;
3444 1.1 mrg int empty;
3445 1.1 mrg
3446 1.1 mrg empty = 0;
3447 1.1 mrg index = 1;
3448 1.1 mrg *start_record = 0;
3449 1.1 mrg
3450 1.1 mrg for (i=0; i<rank; i++)
3451 1.1 mrg {
3452 1.1 mrg ls[i].idx = GFC_DESCRIPTOR_LBOUND(desc,i);
3453 1.1 mrg ls[i].start = GFC_DESCRIPTOR_LBOUND(desc,i);
3454 1.1 mrg ls[i].end = GFC_DESCRIPTOR_UBOUND(desc,i);
3455 1.1 mrg ls[i].step = GFC_DESCRIPTOR_STRIDE(desc,i);
3456 1.1 mrg empty = empty || (GFC_DESCRIPTOR_UBOUND(desc,i)
3457 1.1 mrg < GFC_DESCRIPTOR_LBOUND(desc,i));
3458 1.1 mrg
3459 1.1 mrg if (GFC_DESCRIPTOR_STRIDE(desc,i) > 0)
3460 1.1 mrg {
3461 1.1 mrg index += (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
3462 1.1 mrg * GFC_DESCRIPTOR_STRIDE(desc,i);
3463 1.1 mrg }
3464 1.1 mrg else
3465 1.1 mrg {
3466 1.1 mrg index -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
3467 1.1 mrg * GFC_DESCRIPTOR_STRIDE(desc,i);
3468 1.1 mrg *start_record -= (GFC_DESCRIPTOR_EXTENT(desc,i) - 1)
3469 1.1 mrg * GFC_DESCRIPTOR_STRIDE(desc,i);
3470 1.1 mrg }
3471 1.1 mrg }
3472 1.1 mrg
3473 1.1 mrg if (empty)
3474 1.1 mrg return 0;
3475 1.1 mrg else
3476 1.1 mrg return index;
3477 1.1 mrg }
3478 1.1 mrg
3479 1.1 mrg /* Determine the index to the next record in an internal unit array by
3480 1.1 mrg by incrementing through the array_loop_spec. */
3481 1.1 mrg
3482 1.1 mrg gfc_offset
3483 1.1 mrg next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
3484 1.1 mrg {
3485 1.1 mrg int i, carry;
3486 1.1 mrg gfc_offset index;
3487 1.1 mrg
3488 1.1 mrg carry = 1;
3489 1.1 mrg index = 0;
3490 1.1 mrg
3491 1.1 mrg for (i = 0; i < dtp->u.p.current_unit->rank; i++)
3492 1.1 mrg {
3493 1.1 mrg if (carry)
3494 1.1 mrg {
3495 1.1 mrg ls[i].idx++;
3496 1.1 mrg if (ls[i].idx > ls[i].end)
3497 1.1 mrg {
3498 1.1 mrg ls[i].idx = ls[i].start;
3499 1.1 mrg carry = 1;
3500 1.1 mrg }
3501 1.1 mrg else
3502 1.1 mrg carry = 0;
3503 1.1 mrg }
3504 1.1 mrg index = index + (ls[i].idx - ls[i].start) * ls[i].step;
3505 1.1 mrg }
3506 1.1 mrg
3507 1.1 mrg *finished = carry;
3508 1.1 mrg
3509 1.1 mrg return index;
3510 1.1 mrg }
3511 1.1 mrg
3512 1.1 mrg
3513 1.1 mrg
3514 1.1 mrg /* Skip to the end of the current record, taking care of an optional
3515 1.1 mrg record marker of size bytes. If the file is not seekable, we
3516 1.1 mrg read chunks of size MAX_READ until we get to the right
3517 1.1 mrg position. */
3518 1.1 mrg
3519 1.1 mrg static void
3520 1.1 mrg skip_record (st_parameter_dt *dtp, gfc_offset bytes)
3521 1.1 mrg {
3522 1.1 mrg ssize_t rlength, readb;
3523 1.1 mrg #define MAX_READ 4096
3524 1.1 mrg char p[MAX_READ];
3525 1.1 mrg
3526 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord += bytes;
3527 1.1 mrg if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
3528 1.1 mrg return;
3529 1.1 mrg
3530 1.1 mrg /* Direct access files do not generate END conditions,
3531 1.1 mrg only I/O errors. */
3532 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
3533 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
3534 1.1 mrg {
3535 1.1 mrg /* Seeking failed, fall back to seeking by reading data. */
3536 1.1 mrg while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
3537 1.1 mrg {
3538 1.1 mrg rlength =
3539 1.1 mrg (MAX_READ < dtp->u.p.current_unit->bytes_left_subrecord) ?
3540 1.1 mrg MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
3541 1.1 mrg
3542 1.1 mrg readb = sread (dtp->u.p.current_unit->s, p, rlength);
3543 1.1 mrg if (readb < 0)
3544 1.1 mrg {
3545 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3546 1.1 mrg return;
3547 1.1 mrg }
3548 1.1 mrg
3549 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord -= readb;
3550 1.1 mrg }
3551 1.1 mrg return;
3552 1.1 mrg }
3553 1.1 mrg dtp->u.p.current_unit->bytes_left_subrecord = 0;
3554 1.1 mrg }
3555 1.1 mrg
3556 1.1 mrg
3557 1.1 mrg /* Advance to the next record reading unformatted files, taking
3558 1.1 mrg care of subrecords. If complete_record is nonzero, we loop
3559 1.1 mrg until all subrecords are cleared. */
3560 1.1 mrg
3561 1.1 mrg static void
3562 1.1 mrg next_record_r_unf (st_parameter_dt *dtp, int complete_record)
3563 1.1 mrg {
3564 1.1 mrg size_t bytes;
3565 1.1 mrg
3566 1.1 mrg bytes = compile_options.record_marker == 0 ?
3567 1.1 mrg sizeof (GFC_INTEGER_4) : compile_options.record_marker;
3568 1.1 mrg
3569 1.1 mrg while(1)
3570 1.1 mrg {
3571 1.1 mrg
3572 1.1 mrg /* Skip over tail */
3573 1.1 mrg
3574 1.1 mrg skip_record (dtp, bytes);
3575 1.1 mrg
3576 1.1 mrg if ( ! (complete_record && dtp->u.p.current_unit->continued))
3577 1.1 mrg return;
3578 1.1 mrg
3579 1.1 mrg us_read (dtp, 1);
3580 1.1 mrg }
3581 1.1 mrg }
3582 1.1 mrg
3583 1.1 mrg
3584 1.1 mrg static gfc_offset
3585 1.1 mrg min_off (gfc_offset a, gfc_offset b)
3586 1.1 mrg {
3587 1.1 mrg return (a < b ? a : b);
3588 1.1 mrg }
3589 1.1 mrg
3590 1.1 mrg
3591 1.1 mrg /* Space to the next record for read mode. */
3592 1.1 mrg
3593 1.1 mrg static void
3594 1.1 mrg next_record_r (st_parameter_dt *dtp, int done)
3595 1.1 mrg {
3596 1.1 mrg gfc_offset record;
3597 1.1 mrg char p;
3598 1.1 mrg int cc;
3599 1.1 mrg
3600 1.1 mrg switch (current_mode (dtp))
3601 1.1 mrg {
3602 1.1 mrg /* No records in unformatted STREAM I/O. */
3603 1.1 mrg case UNFORMATTED_STREAM:
3604 1.1 mrg return;
3605 1.1 mrg
3606 1.1 mrg case UNFORMATTED_SEQUENTIAL:
3607 1.1 mrg next_record_r_unf (dtp, 1);
3608 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
3609 1.1 mrg break;
3610 1.1 mrg
3611 1.1 mrg case FORMATTED_DIRECT:
3612 1.1 mrg case UNFORMATTED_DIRECT:
3613 1.1 mrg skip_record (dtp, dtp->u.p.current_unit->bytes_left);
3614 1.1 mrg break;
3615 1.1 mrg
3616 1.1 mrg case FORMATTED_STREAM:
3617 1.1 mrg case FORMATTED_SEQUENTIAL:
3618 1.1 mrg /* read_sf has already terminated input because of an '\n', or
3619 1.1 mrg we have hit EOF. */
3620 1.1 mrg if (dtp->u.p.sf_seen_eor)
3621 1.1 mrg {
3622 1.1 mrg dtp->u.p.sf_seen_eor = 0;
3623 1.1 mrg break;
3624 1.1 mrg }
3625 1.1 mrg
3626 1.1 mrg if (is_internal_unit (dtp))
3627 1.1 mrg {
3628 1.1 mrg if (is_array_io (dtp))
3629 1.1 mrg {
3630 1.1 mrg int finished;
3631 1.1 mrg
3632 1.1 mrg record = next_array_record (dtp, dtp->u.p.current_unit->ls,
3633 1.1 mrg &finished);
3634 1.1 mrg if (!done && finished)
3635 1.1 mrg hit_eof (dtp);
3636 1.1 mrg
3637 1.1 mrg /* Now seek to this record. */
3638 1.1 mrg record = record * dtp->u.p.current_unit->recl;
3639 1.1 mrg if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
3640 1.1 mrg {
3641 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3642 1.1 mrg break;
3643 1.1 mrg }
3644 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
3645 1.1 mrg }
3646 1.1 mrg else
3647 1.1 mrg {
3648 1.1 mrg gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
3649 1.1 mrg bytes_left = min_off (bytes_left,
3650 1.1 mrg ssize (dtp->u.p.current_unit->s)
3651 1.1 mrg - stell (dtp->u.p.current_unit->s));
3652 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
3653 1.1 mrg bytes_left, SEEK_CUR) < 0)
3654 1.1 mrg {
3655 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3656 1.1 mrg break;
3657 1.1 mrg }
3658 1.1 mrg dtp->u.p.current_unit->bytes_left
3659 1.1 mrg = dtp->u.p.current_unit->recl;
3660 1.1 mrg }
3661 1.1 mrg break;
3662 1.1 mrg }
3663 1.1 mrg else if (dtp->u.p.current_unit->flags.cc != CC_NONE)
3664 1.1 mrg {
3665 1.1 mrg do
3666 1.1 mrg {
3667 1.1 mrg errno = 0;
3668 1.1 mrg cc = fbuf_getc (dtp->u.p.current_unit);
3669 1.1 mrg if (cc == EOF)
3670 1.1 mrg {
3671 1.1 mrg if (errno != 0)
3672 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3673 1.1 mrg else
3674 1.1 mrg {
3675 1.1 mrg if (is_stream_io (dtp)
3676 1.1 mrg || dtp->u.p.current_unit->pad_status == PAD_NO
3677 1.1 mrg || dtp->u.p.current_unit->bytes_left
3678 1.1 mrg == dtp->u.p.current_unit->recl)
3679 1.1 mrg hit_eof (dtp);
3680 1.1 mrg }
3681 1.1 mrg break;
3682 1.1 mrg }
3683 1.1 mrg
3684 1.1 mrg if (is_stream_io (dtp))
3685 1.1 mrg dtp->u.p.current_unit->strm_pos++;
3686 1.1 mrg
3687 1.1 mrg p = (char) cc;
3688 1.1 mrg }
3689 1.1 mrg while (p != '\n');
3690 1.1 mrg }
3691 1.1 mrg break;
3692 1.1.1.2 mrg case FORMATTED_UNSPECIFIED:
3693 1.1.1.2 mrg gcc_unreachable ();
3694 1.1 mrg }
3695 1.1 mrg }
3696 1.1 mrg
3697 1.1 mrg
3698 1.1 mrg /* Small utility function to write a record marker, taking care of
3699 1.1 mrg byte swapping and of choosing the correct size. */
3700 1.1 mrg
3701 1.1 mrg static int
3702 1.1 mrg write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
3703 1.1 mrg {
3704 1.1 mrg size_t len;
3705 1.1 mrg GFC_INTEGER_4 buf4;
3706 1.1 mrg GFC_INTEGER_8 buf8;
3707 1.1 mrg
3708 1.1 mrg if (compile_options.record_marker == 0)
3709 1.1 mrg len = sizeof (GFC_INTEGER_4);
3710 1.1 mrg else
3711 1.1 mrg len = compile_options.record_marker;
3712 1.1 mrg
3713 1.1 mrg /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
3714 1.1 mrg if (likely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_NATIVE))
3715 1.1 mrg {
3716 1.1 mrg switch (len)
3717 1.1 mrg {
3718 1.1 mrg case sizeof (GFC_INTEGER_4):
3719 1.1 mrg buf4 = buf;
3720 1.1 mrg return swrite (dtp->u.p.current_unit->s, &buf4, len);
3721 1.1 mrg break;
3722 1.1 mrg
3723 1.1 mrg case sizeof (GFC_INTEGER_8):
3724 1.1 mrg buf8 = buf;
3725 1.1 mrg return swrite (dtp->u.p.current_unit->s, &buf8, len);
3726 1.1 mrg break;
3727 1.1 mrg
3728 1.1 mrg default:
3729 1.1 mrg runtime_error ("Illegal value for record marker");
3730 1.1 mrg break;
3731 1.1 mrg }
3732 1.1 mrg }
3733 1.1 mrg else
3734 1.1 mrg {
3735 1.1 mrg uint32_t u32;
3736 1.1 mrg uint64_t u64;
3737 1.1 mrg switch (len)
3738 1.1 mrg {
3739 1.1 mrg case sizeof (GFC_INTEGER_4):
3740 1.1 mrg buf4 = buf;
3741 1.1 mrg memcpy (&u32, &buf4, sizeof (u32));
3742 1.1 mrg u32 = __builtin_bswap32 (u32);
3743 1.1 mrg return swrite (dtp->u.p.current_unit->s, &u32, len);
3744 1.1 mrg break;
3745 1.1 mrg
3746 1.1 mrg case sizeof (GFC_INTEGER_8):
3747 1.1 mrg buf8 = buf;
3748 1.1 mrg memcpy (&u64, &buf8, sizeof (u64));
3749 1.1 mrg u64 = __builtin_bswap64 (u64);
3750 1.1 mrg return swrite (dtp->u.p.current_unit->s, &u64, len);
3751 1.1 mrg break;
3752 1.1 mrg
3753 1.1 mrg default:
3754 1.1 mrg runtime_error ("Illegal value for record marker");
3755 1.1 mrg break;
3756 1.1 mrg }
3757 1.1 mrg }
3758 1.1 mrg
3759 1.1 mrg }
3760 1.1 mrg
3761 1.1 mrg /* Position to the next (sub)record in write mode for
3762 1.1 mrg unformatted sequential files. */
3763 1.1 mrg
3764 1.1 mrg static void
3765 1.1 mrg next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
3766 1.1 mrg {
3767 1.1 mrg gfc_offset m, m_write, record_marker;
3768 1.1 mrg
3769 1.1 mrg /* Bytes written. */
3770 1.1 mrg m = dtp->u.p.current_unit->recl_subrecord
3771 1.1 mrg - dtp->u.p.current_unit->bytes_left_subrecord;
3772 1.1 mrg
3773 1.1 mrg if (compile_options.record_marker == 0)
3774 1.1 mrg record_marker = sizeof (GFC_INTEGER_4);
3775 1.1 mrg else
3776 1.1 mrg record_marker = compile_options.record_marker;
3777 1.1 mrg
3778 1.1 mrg /* Seek to the head and overwrite the bogus length with the real
3779 1.1 mrg length. */
3780 1.1 mrg
3781 1.1 mrg if (unlikely (sseek (dtp->u.p.current_unit->s, - m - record_marker,
3782 1.1 mrg SEEK_CUR) < 0))
3783 1.1 mrg goto io_error;
3784 1.1 mrg
3785 1.1 mrg if (next_subrecord)
3786 1.1 mrg m_write = -m;
3787 1.1 mrg else
3788 1.1 mrg m_write = m;
3789 1.1 mrg
3790 1.1 mrg if (unlikely (write_us_marker (dtp, m_write) < 0))
3791 1.1 mrg goto io_error;
3792 1.1 mrg
3793 1.1 mrg /* Seek past the end of the current record. */
3794 1.1 mrg
3795 1.1 mrg if (unlikely (sseek (dtp->u.p.current_unit->s, m, SEEK_CUR) < 0))
3796 1.1 mrg goto io_error;
3797 1.1 mrg
3798 1.1 mrg /* Write the length tail. If we finish a record containing
3799 1.1 mrg subrecords, we write out the negative length. */
3800 1.1 mrg
3801 1.1 mrg if (dtp->u.p.current_unit->continued)
3802 1.1 mrg m_write = -m;
3803 1.1 mrg else
3804 1.1 mrg m_write = m;
3805 1.1 mrg
3806 1.1 mrg if (unlikely (write_us_marker (dtp, m_write) < 0))
3807 1.1 mrg goto io_error;
3808 1.1 mrg
3809 1.1 mrg return;
3810 1.1 mrg
3811 1.1 mrg io_error:
3812 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3813 1.1 mrg return;
3814 1.1 mrg
3815 1.1 mrg }
3816 1.1 mrg
3817 1.1 mrg
3818 1.1 mrg /* Utility function like memset() but operating on streams. Return
3819 1.1 mrg value is same as for POSIX write(). */
3820 1.1 mrg
3821 1.1 mrg static gfc_offset
3822 1.1 mrg sset (stream *s, int c, gfc_offset nbyte)
3823 1.1 mrg {
3824 1.1 mrg #define WRITE_CHUNK 256
3825 1.1 mrg char p[WRITE_CHUNK];
3826 1.1 mrg gfc_offset bytes_left;
3827 1.1 mrg ssize_t trans;
3828 1.1 mrg
3829 1.1 mrg if (nbyte < WRITE_CHUNK)
3830 1.1 mrg memset (p, c, nbyte);
3831 1.1 mrg else
3832 1.1 mrg memset (p, c, WRITE_CHUNK);
3833 1.1 mrg
3834 1.1 mrg bytes_left = nbyte;
3835 1.1 mrg while (bytes_left > 0)
3836 1.1 mrg {
3837 1.1 mrg trans = (bytes_left < WRITE_CHUNK) ? bytes_left : WRITE_CHUNK;
3838 1.1 mrg trans = swrite (s, p, trans);
3839 1.1 mrg if (trans <= 0)
3840 1.1 mrg return trans;
3841 1.1 mrg bytes_left -= trans;
3842 1.1 mrg }
3843 1.1 mrg
3844 1.1 mrg return nbyte - bytes_left;
3845 1.1 mrg }
3846 1.1 mrg
3847 1.1 mrg
3848 1.1 mrg /* Finish up a record according to the legacy carriagecontrol type, based
3849 1.1 mrg on the first character in the record. */
3850 1.1 mrg
3851 1.1 mrg static void
3852 1.1 mrg next_record_cc (st_parameter_dt *dtp)
3853 1.1 mrg {
3854 1.1 mrg /* Only valid with CARRIAGECONTROL=FORTRAN. */
3855 1.1 mrg if (dtp->u.p.current_unit->flags.cc != CC_FORTRAN)
3856 1.1 mrg return;
3857 1.1 mrg
3858 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
3859 1.1 mrg if (dtp->u.p.cc.len > 0)
3860 1.1 mrg {
3861 1.1 mrg char *p = fbuf_alloc (dtp->u.p.current_unit, dtp->u.p.cc.len);
3862 1.1 mrg if (!p)
3863 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
3864 1.1 mrg
3865 1.1 mrg /* Output CR for the first character with default CC setting. */
3866 1.1 mrg *(p++) = dtp->u.p.cc.u.end;
3867 1.1 mrg if (dtp->u.p.cc.len > 1)
3868 1.1 mrg *p = dtp->u.p.cc.u.end;
3869 1.1 mrg }
3870 1.1 mrg }
3871 1.1 mrg
3872 1.1 mrg /* Position to the next record in write mode. */
3873 1.1 mrg
3874 1.1 mrg static void
3875 1.1 mrg next_record_w (st_parameter_dt *dtp, int done)
3876 1.1 mrg {
3877 1.1 mrg gfc_offset max_pos_off;
3878 1.1 mrg
3879 1.1 mrg /* Zero counters for X- and T-editing. */
3880 1.1 mrg max_pos_off = dtp->u.p.max_pos;
3881 1.1 mrg dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
3882 1.1 mrg
3883 1.1 mrg switch (current_mode (dtp))
3884 1.1 mrg {
3885 1.1 mrg /* No records in unformatted STREAM I/O. */
3886 1.1 mrg case UNFORMATTED_STREAM:
3887 1.1 mrg return;
3888 1.1 mrg
3889 1.1 mrg case FORMATTED_DIRECT:
3890 1.1 mrg if (dtp->u.p.current_unit->bytes_left == 0)
3891 1.1 mrg break;
3892 1.1 mrg
3893 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
3894 1.1 mrg fbuf_flush (dtp->u.p.current_unit, WRITING);
3895 1.1 mrg if (sset (dtp->u.p.current_unit->s, ' ',
3896 1.1 mrg dtp->u.p.current_unit->bytes_left)
3897 1.1 mrg != dtp->u.p.current_unit->bytes_left)
3898 1.1 mrg goto io_error;
3899 1.1 mrg
3900 1.1 mrg break;
3901 1.1 mrg
3902 1.1 mrg case UNFORMATTED_DIRECT:
3903 1.1 mrg if (dtp->u.p.current_unit->bytes_left > 0)
3904 1.1 mrg {
3905 1.1 mrg gfc_offset length = dtp->u.p.current_unit->bytes_left;
3906 1.1 mrg if (sset (dtp->u.p.current_unit->s, 0, length) != length)
3907 1.1 mrg goto io_error;
3908 1.1 mrg }
3909 1.1 mrg break;
3910 1.1 mrg
3911 1.1 mrg case UNFORMATTED_SEQUENTIAL:
3912 1.1 mrg next_record_w_unf (dtp, 0);
3913 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
3914 1.1 mrg break;
3915 1.1 mrg
3916 1.1 mrg case FORMATTED_STREAM:
3917 1.1 mrg case FORMATTED_SEQUENTIAL:
3918 1.1 mrg
3919 1.1 mrg if (is_internal_unit (dtp))
3920 1.1 mrg {
3921 1.1 mrg char *p;
3922 1.1 mrg /* Internal unit, so must fit in memory. */
3923 1.1 mrg size_t length, m;
3924 1.1 mrg size_t max_pos = max_pos_off;
3925 1.1 mrg if (is_array_io (dtp))
3926 1.1 mrg {
3927 1.1 mrg int finished;
3928 1.1 mrg
3929 1.1 mrg length = dtp->u.p.current_unit->bytes_left;
3930 1.1 mrg
3931 1.1 mrg /* If the farthest position reached is greater than current
3932 1.1 mrg position, adjust the position and set length to pad out
3933 1.1 mrg whats left. Otherwise just pad whats left.
3934 1.1 mrg (for character array unit) */
3935 1.1 mrg m = dtp->u.p.current_unit->recl
3936 1.1 mrg - dtp->u.p.current_unit->bytes_left;
3937 1.1 mrg if (max_pos > m)
3938 1.1 mrg {
3939 1.1 mrg length = (max_pos - m);
3940 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
3941 1.1 mrg length, SEEK_CUR) < 0)
3942 1.1 mrg {
3943 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3944 1.1 mrg return;
3945 1.1 mrg }
3946 1.1 mrg length = ((size_t) dtp->u.p.current_unit->recl - max_pos);
3947 1.1 mrg }
3948 1.1 mrg
3949 1.1 mrg p = write_block (dtp, length);
3950 1.1 mrg if (p == NULL)
3951 1.1 mrg return;
3952 1.1 mrg
3953 1.1 mrg if (unlikely (is_char4_unit (dtp)))
3954 1.1 mrg {
3955 1.1 mrg gfc_char4_t *p4 = (gfc_char4_t *) p;
3956 1.1 mrg memset4 (p4, ' ', length);
3957 1.1 mrg }
3958 1.1 mrg else
3959 1.1 mrg memset (p, ' ', length);
3960 1.1 mrg
3961 1.1 mrg /* Now that the current record has been padded out,
3962 1.1 mrg determine where the next record in the array is.
3963 1.1 mrg Note that this can return a negative value, so it
3964 1.1 mrg needs to be assigned to a signed value. */
3965 1.1 mrg gfc_offset record = next_array_record
3966 1.1 mrg (dtp, dtp->u.p.current_unit->ls, &finished);
3967 1.1 mrg if (finished)
3968 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
3969 1.1 mrg
3970 1.1 mrg /* Now seek to this record */
3971 1.1 mrg record = record * dtp->u.p.current_unit->recl;
3972 1.1 mrg
3973 1.1 mrg if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
3974 1.1 mrg {
3975 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3976 1.1 mrg return;
3977 1.1 mrg }
3978 1.1 mrg
3979 1.1 mrg dtp->u.p.current_unit->bytes_left = dtp->u.p.current_unit->recl;
3980 1.1 mrg }
3981 1.1 mrg else
3982 1.1 mrg {
3983 1.1 mrg length = 1;
3984 1.1 mrg
3985 1.1 mrg /* If this is the last call to next_record move to the farthest
3986 1.1 mrg position reached and set length to pad out the remainder
3987 1.1 mrg of the record. (for character scaler unit) */
3988 1.1 mrg if (done)
3989 1.1 mrg {
3990 1.1 mrg m = dtp->u.p.current_unit->recl
3991 1.1 mrg - dtp->u.p.current_unit->bytes_left;
3992 1.1 mrg if (max_pos > m)
3993 1.1 mrg {
3994 1.1 mrg length = max_pos - m;
3995 1.1 mrg if (sseek (dtp->u.p.current_unit->s,
3996 1.1 mrg length, SEEK_CUR) < 0)
3997 1.1 mrg {
3998 1.1 mrg generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
3999 1.1 mrg return;
4000 1.1 mrg }
4001 1.1 mrg length = (size_t) dtp->u.p.current_unit->recl
4002 1.1 mrg - max_pos;
4003 1.1 mrg }
4004 1.1 mrg else
4005 1.1 mrg length = dtp->u.p.current_unit->bytes_left;
4006 1.1 mrg }
4007 1.1 mrg if (length > 0)
4008 1.1 mrg {
4009 1.1 mrg p = write_block (dtp, length);
4010 1.1 mrg if (p == NULL)
4011 1.1 mrg return;
4012 1.1 mrg
4013 1.1 mrg if (unlikely (is_char4_unit (dtp)))
4014 1.1 mrg {
4015 1.1 mrg gfc_char4_t *p4 = (gfc_char4_t *) p;
4016 1.1 mrg memset4 (p4, (gfc_char4_t) ' ', length);
4017 1.1 mrg }
4018 1.1 mrg else
4019 1.1 mrg memset (p, ' ', length);
4020 1.1 mrg }
4021 1.1 mrg }
4022 1.1 mrg }
4023 1.1 mrg /* Handle legacy CARRIAGECONTROL line endings. */
4024 1.1 mrg else if (dtp->u.p.current_unit->flags.cc == CC_FORTRAN)
4025 1.1 mrg next_record_cc (dtp);
4026 1.1 mrg else
4027 1.1 mrg {
4028 1.1 mrg /* Skip newlines for CC=CC_NONE. */
4029 1.1 mrg const int len = (dtp->u.p.current_unit->flags.cc == CC_NONE)
4030 1.1 mrg ? 0
4031 1.1 mrg #ifdef HAVE_CRLF
4032 1.1 mrg : 2;
4033 1.1 mrg #else
4034 1.1 mrg : 1;
4035 1.1 mrg #endif
4036 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
4037 1.1 mrg if (dtp->u.p.current_unit->flags.cc != CC_NONE)
4038 1.1 mrg {
4039 1.1 mrg char *p = fbuf_alloc (dtp->u.p.current_unit, len);
4040 1.1 mrg if (!p)
4041 1.1 mrg goto io_error;
4042 1.1 mrg #ifdef HAVE_CRLF
4043 1.1 mrg *(p++) = '\r';
4044 1.1 mrg #endif
4045 1.1 mrg *p = '\n';
4046 1.1 mrg }
4047 1.1 mrg if (is_stream_io (dtp))
4048 1.1 mrg {
4049 1.1 mrg dtp->u.p.current_unit->strm_pos += len;
4050 1.1 mrg if (dtp->u.p.current_unit->strm_pos
4051 1.1 mrg < ssize (dtp->u.p.current_unit->s))
4052 1.1 mrg unit_truncate (dtp->u.p.current_unit,
4053 1.1 mrg dtp->u.p.current_unit->strm_pos - 1,
4054 1.1 mrg &dtp->common);
4055 1.1 mrg }
4056 1.1 mrg }
4057 1.1 mrg
4058 1.1 mrg break;
4059 1.1.1.2 mrg case FORMATTED_UNSPECIFIED:
4060 1.1.1.2 mrg gcc_unreachable ();
4061 1.1 mrg
4062 1.1 mrg io_error:
4063 1.1 mrg generate_error (&dtp->common, LIBERROR_OS, NULL);
4064 1.1 mrg break;
4065 1.1 mrg }
4066 1.1 mrg }
4067 1.1 mrg
4068 1.1 mrg /* Position to the next record, which means moving to the end of the
4069 1.1 mrg current record. This can happen under several different
4070 1.1 mrg conditions. If the done flag is not set, we get ready to process
4071 1.1 mrg the next record. */
4072 1.1 mrg
4073 1.1 mrg void
4074 1.1 mrg next_record (st_parameter_dt *dtp, int done)
4075 1.1 mrg {
4076 1.1 mrg gfc_offset fp; /* File position. */
4077 1.1 mrg
4078 1.1 mrg dtp->u.p.current_unit->read_bad = 0;
4079 1.1 mrg
4080 1.1 mrg if (dtp->u.p.mode == READING)
4081 1.1 mrg next_record_r (dtp, done);
4082 1.1 mrg else
4083 1.1 mrg next_record_w (dtp, done);
4084 1.1 mrg
4085 1.1 mrg fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
4086 1.1 mrg
4087 1.1 mrg if (!is_stream_io (dtp))
4088 1.1 mrg {
4089 1.1 mrg /* Since we have changed the position, set it to unspecified so
4090 1.1 mrg that INQUIRE(POSITION=) knows it needs to look into it. */
4091 1.1 mrg if (done)
4092 1.1 mrg dtp->u.p.current_unit->flags.position = POSITION_UNSPECIFIED;
4093 1.1 mrg
4094 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4095 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_DIRECT)
4096 1.1 mrg {
4097 1.1 mrg fp = stell (dtp->u.p.current_unit->s);
4098 1.1 mrg /* Calculate next record, rounding up partial records. */
4099 1.1 mrg dtp->u.p.current_unit->last_record =
4100 1.1 mrg (fp + dtp->u.p.current_unit->recl) /
4101 1.1 mrg dtp->u.p.current_unit->recl - 1;
4102 1.1 mrg }
4103 1.1 mrg else
4104 1.1 mrg dtp->u.p.current_unit->last_record++;
4105 1.1 mrg }
4106 1.1 mrg
4107 1.1 mrg if (!done)
4108 1.1 mrg pre_position (dtp);
4109 1.1 mrg
4110 1.1 mrg smarkeor (dtp->u.p.current_unit->s);
4111 1.1 mrg }
4112 1.1 mrg
4113 1.1 mrg
4114 1.1 mrg /* Finalize the current data transfer. For a nonadvancing transfer,
4115 1.1 mrg this means advancing to the next record. For internal units close the
4116 1.1 mrg stream associated with the unit. */
4117 1.1 mrg
4118 1.1 mrg static void
4119 1.1 mrg finalize_transfer (st_parameter_dt *dtp)
4120 1.1 mrg {
4121 1.1 mrg GFC_INTEGER_4 cf = dtp->common.flags;
4122 1.1 mrg
4123 1.1 mrg if ((dtp->u.p.ionml != NULL)
4124 1.1 mrg && (cf & IOPARM_DT_HAS_NAMELIST_NAME) != 0)
4125 1.1 mrg {
4126 1.1 mrg dtp->u.p.namelist_mode = 1;
4127 1.1 mrg if ((cf & IOPARM_DT_NAMELIST_READ_MODE) != 0)
4128 1.1 mrg namelist_read (dtp);
4129 1.1 mrg else
4130 1.1 mrg namelist_write (dtp);
4131 1.1 mrg }
4132 1.1 mrg
4133 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
4134 1.1 mrg *dtp->size = dtp->u.p.current_unit->size_used;
4135 1.1 mrg
4136 1.1 mrg if (dtp->u.p.eor_condition)
4137 1.1 mrg {
4138 1.1 mrg generate_error (&dtp->common, LIBERROR_EOR, NULL);
4139 1.1 mrg goto done;
4140 1.1 mrg }
4141 1.1 mrg
4142 1.1 mrg if (dtp->u.p.current_unit && (dtp->u.p.current_unit->child_dtio > 0))
4143 1.1 mrg {
4144 1.1 mrg if (cf & IOPARM_DT_HAS_FORMAT)
4145 1.1 mrg {
4146 1.1 mrg free (dtp->u.p.fmt);
4147 1.1 mrg free (dtp->format);
4148 1.1 mrg }
4149 1.1 mrg return;
4150 1.1 mrg }
4151 1.1 mrg
4152 1.1 mrg if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
4153 1.1 mrg {
4154 1.1 mrg if (dtp->u.p.current_unit && current_mode (dtp) == UNFORMATTED_SEQUENTIAL)
4155 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4156 1.1 mrg goto done;
4157 1.1 mrg }
4158 1.1 mrg
4159 1.1 mrg dtp->u.p.transfer = NULL;
4160 1.1 mrg if (dtp->u.p.current_unit == NULL)
4161 1.1 mrg goto done;
4162 1.1 mrg
4163 1.1 mrg if ((cf & IOPARM_DT_LIST_FORMAT) != 0 && dtp->u.p.mode == READING)
4164 1.1 mrg {
4165 1.1 mrg finish_list_read (dtp);
4166 1.1 mrg goto done;
4167 1.1 mrg }
4168 1.1 mrg
4169 1.1 mrg if (dtp->u.p.mode == WRITING)
4170 1.1 mrg dtp->u.p.current_unit->previous_nonadvancing_write
4171 1.1 mrg = dtp->u.p.advance_status == ADVANCE_NO;
4172 1.1 mrg
4173 1.1 mrg if (is_stream_io (dtp))
4174 1.1 mrg {
4175 1.1 mrg if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
4176 1.1 mrg && dtp->u.p.advance_status != ADVANCE_NO)
4177 1.1 mrg next_record (dtp, 1);
4178 1.1 mrg
4179 1.1 mrg goto done;
4180 1.1 mrg }
4181 1.1 mrg
4182 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4183 1.1 mrg
4184 1.1 mrg if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
4185 1.1 mrg {
4186 1.1 mrg fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
4187 1.1 mrg dtp->u.p.seen_dollar = 0;
4188 1.1 mrg goto done;
4189 1.1 mrg }
4190 1.1 mrg
4191 1.1 mrg /* For non-advancing I/O, save the current maximum position for use in the
4192 1.1 mrg next I/O operation if needed. */
4193 1.1 mrg if (dtp->u.p.advance_status == ADVANCE_NO)
4194 1.1 mrg {
4195 1.1 mrg if (dtp->u.p.skips > 0)
4196 1.1 mrg {
4197 1.1 mrg int tmp;
4198 1.1 mrg write_x (dtp, dtp->u.p.skips, dtp->u.p.pending_spaces);
4199 1.1 mrg tmp = (int)(dtp->u.p.current_unit->recl
4200 1.1 mrg - dtp->u.p.current_unit->bytes_left);
4201 1.1 mrg dtp->u.p.max_pos =
4202 1.1 mrg dtp->u.p.max_pos > tmp ? dtp->u.p.max_pos : tmp;
4203 1.1 mrg dtp->u.p.skips = 0;
4204 1.1 mrg }
4205 1.1 mrg int bytes_written = (int) (dtp->u.p.current_unit->recl
4206 1.1 mrg - dtp->u.p.current_unit->bytes_left);
4207 1.1 mrg dtp->u.p.current_unit->saved_pos =
4208 1.1 mrg dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
4209 1.1 mrg fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
4210 1.1 mrg goto done;
4211 1.1 mrg }
4212 1.1 mrg else if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED
4213 1.1 mrg && dtp->u.p.mode == WRITING && !is_internal_unit (dtp))
4214 1.1 mrg fbuf_seek (dtp->u.p.current_unit, 0, SEEK_END);
4215 1.1 mrg
4216 1.1 mrg dtp->u.p.current_unit->saved_pos = 0;
4217 1.1 mrg dtp->u.p.current_unit->last_char = EOF - 1;
4218 1.1 mrg next_record (dtp, 1);
4219 1.1 mrg
4220 1.1 mrg done:
4221 1.1 mrg
4222 1.1 mrg if (dtp->u.p.unit_is_internal)
4223 1.1 mrg {
4224 1.1 mrg /* The unit structure may be reused later so clear the
4225 1.1 mrg internal unit kind. */
4226 1.1 mrg dtp->u.p.current_unit->internal_unit_kind = 0;
4227 1.1 mrg
4228 1.1 mrg fbuf_destroy (dtp->u.p.current_unit);
4229 1.1 mrg if (dtp->u.p.current_unit
4230 1.1 mrg && (dtp->u.p.current_unit->child_dtio == 0)
4231 1.1 mrg && dtp->u.p.current_unit->s)
4232 1.1 mrg {
4233 1.1 mrg sclose (dtp->u.p.current_unit->s);
4234 1.1 mrg dtp->u.p.current_unit->s = NULL;
4235 1.1 mrg }
4236 1.1 mrg }
4237 1.1 mrg
4238 1.1 mrg #ifdef HAVE_USELOCALE
4239 1.1 mrg if (dtp->u.p.old_locale != (locale_t) 0)
4240 1.1 mrg {
4241 1.1 mrg uselocale (dtp->u.p.old_locale);
4242 1.1 mrg dtp->u.p.old_locale = (locale_t) 0;
4243 1.1 mrg }
4244 1.1 mrg #else
4245 1.1 mrg __gthread_mutex_lock (&old_locale_lock);
4246 1.1 mrg if (!--old_locale_ctr)
4247 1.1 mrg {
4248 1.1 mrg setlocale (LC_NUMERIC, old_locale);
4249 1.1 mrg old_locale = NULL;
4250 1.1 mrg }
4251 1.1 mrg __gthread_mutex_unlock (&old_locale_lock);
4252 1.1 mrg #endif
4253 1.1 mrg }
4254 1.1 mrg
4255 1.1 mrg /* Transfer function for IOLENGTH. It doesn't actually do any
4256 1.1 mrg data transfer, it just updates the length counter. */
4257 1.1 mrg
4258 1.1 mrg static void
4259 1.1 mrg iolength_transfer (st_parameter_dt *dtp, bt type __attribute__((unused)),
4260 1.1 mrg void *dest __attribute__ ((unused)),
4261 1.1 mrg int kind __attribute__((unused)),
4262 1.1 mrg size_t size, size_t nelems)
4263 1.1 mrg {
4264 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
4265 1.1 mrg *dtp->iolength += (GFC_IO_INT) (size * nelems);
4266 1.1 mrg }
4267 1.1 mrg
4268 1.1 mrg
4269 1.1 mrg /* Initialize the IOLENGTH data transfer. This function is in essence
4270 1.1 mrg a very much simplified version of data_transfer_init(), because it
4271 1.1 mrg doesn't have to deal with units at all. */
4272 1.1 mrg
4273 1.1 mrg static void
4274 1.1 mrg iolength_transfer_init (st_parameter_dt *dtp)
4275 1.1 mrg {
4276 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_IOLENGTH) != 0)
4277 1.1 mrg *dtp->iolength = 0;
4278 1.1 mrg
4279 1.1 mrg memset (&dtp->u.p, 0, sizeof (dtp->u.p));
4280 1.1 mrg
4281 1.1 mrg /* Set up the subroutine that will handle the transfers. */
4282 1.1 mrg
4283 1.1 mrg dtp->u.p.transfer = iolength_transfer;
4284 1.1 mrg }
4285 1.1 mrg
4286 1.1 mrg
4287 1.1 mrg /* Library entry point for the IOLENGTH form of the INQUIRE
4288 1.1 mrg statement. The IOLENGTH form requires no I/O to be performed, but
4289 1.1 mrg it must still be a runtime library call so that we can determine
4290 1.1 mrg the iolength for dynamic arrays and such. */
4291 1.1 mrg
4292 1.1 mrg extern void st_iolength (st_parameter_dt *);
4293 1.1 mrg export_proto(st_iolength);
4294 1.1 mrg
4295 1.1 mrg void
4296 1.1 mrg st_iolength (st_parameter_dt *dtp)
4297 1.1 mrg {
4298 1.1 mrg library_start (&dtp->common);
4299 1.1 mrg iolength_transfer_init (dtp);
4300 1.1 mrg }
4301 1.1 mrg
4302 1.1 mrg extern void st_iolength_done (st_parameter_dt *);
4303 1.1 mrg export_proto(st_iolength_done);
4304 1.1 mrg
4305 1.1 mrg void
4306 1.1 mrg st_iolength_done (st_parameter_dt *dtp __attribute__((unused)))
4307 1.1 mrg {
4308 1.1 mrg free_ionml (dtp);
4309 1.1 mrg library_end ();
4310 1.1 mrg }
4311 1.1 mrg
4312 1.1 mrg
4313 1.1 mrg /* The READ statement. */
4314 1.1 mrg
4315 1.1 mrg extern void st_read (st_parameter_dt *);
4316 1.1 mrg export_proto(st_read);
4317 1.1 mrg
4318 1.1 mrg void
4319 1.1 mrg st_read (st_parameter_dt *dtp)
4320 1.1 mrg {
4321 1.1 mrg library_start (&dtp->common);
4322 1.1 mrg
4323 1.1 mrg data_transfer_init (dtp, 1);
4324 1.1 mrg }
4325 1.1 mrg
4326 1.1 mrg extern void st_read_done (st_parameter_dt *);
4327 1.1 mrg export_proto(st_read_done);
4328 1.1 mrg
4329 1.1 mrg void
4330 1.1 mrg st_read_done_worker (st_parameter_dt *dtp)
4331 1.1 mrg {
4332 1.1 mrg finalize_transfer (dtp);
4333 1.1 mrg
4334 1.1 mrg free_ionml (dtp);
4335 1.1 mrg
4336 1.1 mrg /* If this is a parent READ statement we do not need to retain the
4337 1.1 mrg internal unit structure for child use. */
4338 1.1 mrg if (dtp->u.p.current_unit != NULL
4339 1.1 mrg && dtp->u.p.current_unit->child_dtio == 0)
4340 1.1 mrg {
4341 1.1 mrg if (dtp->u.p.unit_is_internal)
4342 1.1 mrg {
4343 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
4344 1.1 mrg {
4345 1.1 mrg free (dtp->u.p.current_unit->filename);
4346 1.1 mrg dtp->u.p.current_unit->filename = NULL;
4347 1.1 mrg if (dtp->u.p.current_unit->ls)
4348 1.1 mrg free (dtp->u.p.current_unit->ls);
4349 1.1 mrg dtp->u.p.current_unit->ls = NULL;
4350 1.1 mrg }
4351 1.1 mrg newunit_free (dtp->common.unit);
4352 1.1 mrg }
4353 1.1 mrg if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
4354 1.1 mrg {
4355 1.1 mrg free_format_data (dtp->u.p.fmt);
4356 1.1 mrg free_format (dtp);
4357 1.1 mrg }
4358 1.1 mrg }
4359 1.1 mrg }
4360 1.1 mrg
4361 1.1 mrg void
4362 1.1 mrg st_read_done (st_parameter_dt *dtp)
4363 1.1 mrg {
4364 1.1 mrg if (dtp->u.p.current_unit)
4365 1.1 mrg {
4366 1.1 mrg if (dtp->u.p.current_unit->au)
4367 1.1 mrg {
4368 1.1 mrg if (dtp->common.flags & IOPARM_DT_HAS_ID)
4369 1.1 mrg *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);
4370 1.1 mrg else
4371 1.1 mrg {
4372 1.1 mrg if (dtp->u.p.async)
4373 1.1 mrg enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
4374 1.1 mrg }
4375 1.1 mrg }
4376 1.1 mrg else
4377 1.1 mrg st_read_done_worker (dtp);
4378 1.1 mrg
4379 1.1 mrg unlock_unit (dtp->u.p.current_unit);
4380 1.1 mrg }
4381 1.1 mrg
4382 1.1 mrg library_end ();
4383 1.1 mrg }
4384 1.1 mrg
4385 1.1 mrg extern void st_write (st_parameter_dt *);
4386 1.1 mrg export_proto (st_write);
4387 1.1 mrg
4388 1.1 mrg void
4389 1.1 mrg st_write (st_parameter_dt *dtp)
4390 1.1 mrg {
4391 1.1 mrg library_start (&dtp->common);
4392 1.1 mrg data_transfer_init (dtp, 0);
4393 1.1 mrg }
4394 1.1 mrg
4395 1.1 mrg
4396 1.1 mrg void
4397 1.1 mrg st_write_done_worker (st_parameter_dt *dtp)
4398 1.1 mrg {
4399 1.1 mrg finalize_transfer (dtp);
4400 1.1 mrg
4401 1.1 mrg if (dtp->u.p.current_unit != NULL
4402 1.1 mrg && dtp->u.p.current_unit->child_dtio == 0)
4403 1.1 mrg {
4404 1.1 mrg /* Deal with endfile conditions associated with sequential files. */
4405 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
4406 1.1 mrg switch (dtp->u.p.current_unit->endfile)
4407 1.1 mrg {
4408 1.1 mrg case AT_ENDFILE: /* Remain at the endfile record. */
4409 1.1 mrg break;
4410 1.1 mrg
4411 1.1 mrg case AFTER_ENDFILE:
4412 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now. */
4413 1.1 mrg break;
4414 1.1 mrg
4415 1.1 mrg case NO_ENDFILE:
4416 1.1 mrg /* Get rid of whatever is after this record. */
4417 1.1 mrg if (!is_internal_unit (dtp))
4418 1.1 mrg unit_truncate (dtp->u.p.current_unit,
4419 1.1 mrg stell (dtp->u.p.current_unit->s),
4420 1.1 mrg &dtp->common);
4421 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4422 1.1 mrg break;
4423 1.1 mrg }
4424 1.1 mrg
4425 1.1 mrg free_ionml (dtp);
4426 1.1 mrg
4427 1.1 mrg /* If this is a parent WRITE statement we do not need to retain the
4428 1.1 mrg internal unit structure for child use. */
4429 1.1 mrg if (dtp->u.p.unit_is_internal)
4430 1.1 mrg {
4431 1.1 mrg if ((dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
4432 1.1 mrg {
4433 1.1 mrg free (dtp->u.p.current_unit->filename);
4434 1.1 mrg dtp->u.p.current_unit->filename = NULL;
4435 1.1 mrg if (dtp->u.p.current_unit->ls)
4436 1.1 mrg free (dtp->u.p.current_unit->ls);
4437 1.1 mrg dtp->u.p.current_unit->ls = NULL;
4438 1.1 mrg }
4439 1.1 mrg newunit_free (dtp->common.unit);
4440 1.1 mrg }
4441 1.1 mrg if (dtp->u.p.unit_is_internal || dtp->u.p.format_not_saved)
4442 1.1 mrg {
4443 1.1 mrg free_format_data (dtp->u.p.fmt);
4444 1.1 mrg free_format (dtp);
4445 1.1 mrg }
4446 1.1 mrg }
4447 1.1 mrg }
4448 1.1 mrg
4449 1.1 mrg extern void st_write_done (st_parameter_dt *);
4450 1.1 mrg export_proto(st_write_done);
4451 1.1 mrg
4452 1.1 mrg void
4453 1.1 mrg st_write_done (st_parameter_dt *dtp)
4454 1.1 mrg {
4455 1.1 mrg if (dtp->u.p.current_unit)
4456 1.1 mrg {
4457 1.1 mrg if (dtp->u.p.current_unit->au && dtp->u.p.async)
4458 1.1 mrg {
4459 1.1 mrg if (dtp->common.flags & IOPARM_DT_HAS_ID)
4460 1.1 mrg *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
4461 1.1 mrg AIO_WRITE_DONE);
4462 1.1 mrg else
4463 1.1 mrg {
4464 1.1 mrg /* We perform synchronous I/O on an asynchronous unit, so no need
4465 1.1 mrg to enqueue AIO_READ_DONE. */
4466 1.1 mrg if (dtp->u.p.async)
4467 1.1 mrg enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
4468 1.1 mrg }
4469 1.1 mrg }
4470 1.1 mrg else
4471 1.1 mrg st_write_done_worker (dtp);
4472 1.1 mrg
4473 1.1 mrg unlock_unit (dtp->u.p.current_unit);
4474 1.1 mrg }
4475 1.1 mrg
4476 1.1 mrg library_end ();
4477 1.1 mrg }
4478 1.1 mrg
4479 1.1 mrg /* Wait operation. We need to keep around the do-nothing version
4480 1.1 mrg of st_wait for compatibility with previous versions, which had marked
4481 1.1 mrg the argument as unused (and thus liable to be removed).
4482 1.1 mrg
4483 1.1 mrg TODO: remove at next bump in version number. */
4484 1.1 mrg
4485 1.1 mrg void
4486 1.1 mrg st_wait (st_parameter_wait *wtp __attribute__((unused)))
4487 1.1 mrg {
4488 1.1 mrg return;
4489 1.1 mrg }
4490 1.1 mrg
4491 1.1 mrg void
4492 1.1 mrg st_wait_async (st_parameter_wait *wtp)
4493 1.1 mrg {
4494 1.1 mrg gfc_unit *u = find_unit (wtp->common.unit);
4495 1.1.1.2 mrg if (ASYNC_IO && u && u->au)
4496 1.1 mrg {
4497 1.1 mrg if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
4498 1.1 mrg async_wait_id (&(wtp->common), u->au, *wtp->id);
4499 1.1 mrg else
4500 1.1 mrg async_wait (&(wtp->common), u->au);
4501 1.1 mrg }
4502 1.1 mrg
4503 1.1 mrg unlock_unit (u);
4504 1.1 mrg }
4505 1.1 mrg
4506 1.1 mrg
4507 1.1 mrg /* Receives the scalar information for namelist objects and stores it
4508 1.1 mrg in a linked list of namelist_info types. */
4509 1.1 mrg
4510 1.1 mrg static void
4511 1.1 mrg set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
4512 1.1 mrg GFC_INTEGER_4 len, gfc_charlen_type string_length,
4513 1.1 mrg dtype_type dtype, void *dtio_sub, void *vtable)
4514 1.1 mrg {
4515 1.1 mrg namelist_info *t1 = NULL;
4516 1.1 mrg namelist_info *nml;
4517 1.1 mrg size_t var_name_len = strlen (var_name);
4518 1.1 mrg
4519 1.1 mrg nml = (namelist_info*) xmalloc (sizeof (namelist_info));
4520 1.1 mrg
4521 1.1 mrg nml->mem_pos = var_addr;
4522 1.1 mrg nml->dtio_sub = dtio_sub;
4523 1.1 mrg nml->vtable = vtable;
4524 1.1 mrg
4525 1.1 mrg nml->var_name = (char*) xmalloc (var_name_len + 1);
4526 1.1 mrg memcpy (nml->var_name, var_name, var_name_len);
4527 1.1 mrg nml->var_name[var_name_len] = '\0';
4528 1.1 mrg
4529 1.1 mrg nml->len = (int) len;
4530 1.1 mrg nml->string_length = (index_type) string_length;
4531 1.1 mrg
4532 1.1 mrg nml->var_rank = (int) (dtype.rank);
4533 1.1 mrg nml->size = (index_type) (dtype.elem_len);
4534 1.1 mrg nml->type = (bt) (dtype.type);
4535 1.1 mrg
4536 1.1 mrg if (nml->var_rank > 0)
4537 1.1 mrg {
4538 1.1 mrg nml->dim = (descriptor_dimension*)
4539 1.1 mrg xmallocarray (nml->var_rank, sizeof (descriptor_dimension));
4540 1.1 mrg nml->ls = (array_loop_spec*)
4541 1.1 mrg xmallocarray (nml->var_rank, sizeof (array_loop_spec));
4542 1.1 mrg }
4543 1.1 mrg else
4544 1.1 mrg {
4545 1.1 mrg nml->dim = NULL;
4546 1.1 mrg nml->ls = NULL;
4547 1.1 mrg }
4548 1.1 mrg
4549 1.1 mrg nml->next = NULL;
4550 1.1 mrg
4551 1.1 mrg if ((dtp->common.flags & IOPARM_DT_IONML_SET) == 0)
4552 1.1 mrg {
4553 1.1 mrg dtp->common.flags |= IOPARM_DT_IONML_SET;
4554 1.1 mrg dtp->u.p.ionml = nml;
4555 1.1 mrg }
4556 1.1 mrg else
4557 1.1 mrg {
4558 1.1 mrg for (t1 = dtp->u.p.ionml; t1->next; t1 = t1->next);
4559 1.1 mrg t1->next = nml;
4560 1.1 mrg }
4561 1.1 mrg }
4562 1.1 mrg
4563 1.1 mrg extern void st_set_nml_var (st_parameter_dt *dtp, void *, char *,
4564 1.1 mrg GFC_INTEGER_4, gfc_charlen_type, dtype_type);
4565 1.1 mrg export_proto(st_set_nml_var);
4566 1.1 mrg
4567 1.1 mrg void
4568 1.1 mrg st_set_nml_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
4569 1.1 mrg GFC_INTEGER_4 len, gfc_charlen_type string_length,
4570 1.1 mrg dtype_type dtype)
4571 1.1 mrg {
4572 1.1 mrg set_nml_var (dtp, var_addr, var_name, len, string_length,
4573 1.1 mrg dtype, NULL, NULL);
4574 1.1 mrg }
4575 1.1 mrg
4576 1.1 mrg
4577 1.1 mrg /* Essentially the same as previous but carrying the dtio procedure
4578 1.1 mrg and the vtable as additional arguments. */
4579 1.1 mrg extern void st_set_nml_dtio_var (st_parameter_dt *dtp, void *, char *,
4580 1.1 mrg GFC_INTEGER_4, gfc_charlen_type, dtype_type,
4581 1.1 mrg void *, void *);
4582 1.1 mrg export_proto(st_set_nml_dtio_var);
4583 1.1 mrg
4584 1.1 mrg
4585 1.1 mrg void
4586 1.1 mrg st_set_nml_dtio_var (st_parameter_dt *dtp, void *var_addr, char *var_name,
4587 1.1 mrg GFC_INTEGER_4 len, gfc_charlen_type string_length,
4588 1.1 mrg dtype_type dtype, void *dtio_sub, void *vtable)
4589 1.1 mrg {
4590 1.1 mrg set_nml_var (dtp, var_addr, var_name, len, string_length,
4591 1.1 mrg dtype, dtio_sub, vtable);
4592 1.1 mrg }
4593 1.1 mrg
4594 1.1 mrg /* Store the dimensional information for the namelist object. */
4595 1.1 mrg extern void st_set_nml_var_dim (st_parameter_dt *, GFC_INTEGER_4,
4596 1.1 mrg index_type, index_type,
4597 1.1 mrg index_type);
4598 1.1 mrg export_proto(st_set_nml_var_dim);
4599 1.1 mrg
4600 1.1 mrg void
4601 1.1 mrg st_set_nml_var_dim (st_parameter_dt *dtp, GFC_INTEGER_4 n_dim,
4602 1.1 mrg index_type stride, index_type lbound,
4603 1.1 mrg index_type ubound)
4604 1.1 mrg {
4605 1.1 mrg namelist_info *nml;
4606 1.1 mrg int n;
4607 1.1 mrg
4608 1.1 mrg n = (int)n_dim;
4609 1.1 mrg
4610 1.1 mrg for (nml = dtp->u.p.ionml; nml->next; nml = nml->next);
4611 1.1 mrg
4612 1.1 mrg GFC_DIMENSION_SET(nml->dim[n],lbound,ubound,stride);
4613 1.1 mrg }
4614 1.1 mrg
4615 1.1 mrg
4616 1.1 mrg /* Once upon a time, a poor innocent Fortran program was reading a
4617 1.1 mrg file, when suddenly it hit the end-of-file (EOF). Unfortunately
4618 1.1 mrg the OS doesn't tell whether we're at the EOF or whether we already
4619 1.1 mrg went past it. Luckily our hero, libgfortran, keeps track of this.
4620 1.1 mrg Call this function when you detect an EOF condition. See Section
4621 1.1 mrg 9.10.2 in F2003. */
4622 1.1 mrg
4623 1.1 mrg void
4624 1.1 mrg hit_eof (st_parameter_dt *dtp)
4625 1.1 mrg {
4626 1.1 mrg dtp->u.p.current_unit->flags.position = POSITION_APPEND;
4627 1.1 mrg
4628 1.1 mrg if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
4629 1.1 mrg switch (dtp->u.p.current_unit->endfile)
4630 1.1 mrg {
4631 1.1 mrg case NO_ENDFILE:
4632 1.1 mrg case AT_ENDFILE:
4633 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
4634 1.1 mrg if (!is_internal_unit (dtp) && !dtp->u.p.namelist_mode)
4635 1.1 mrg {
4636 1.1 mrg dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
4637 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4638 1.1 mrg }
4639 1.1 mrg else
4640 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4641 1.1 mrg break;
4642 1.1 mrg
4643 1.1 mrg case AFTER_ENDFILE:
4644 1.1 mrg generate_error (&dtp->common, LIBERROR_ENDFILE, NULL);
4645 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4646 1.1 mrg break;
4647 1.1 mrg }
4648 1.1 mrg else
4649 1.1 mrg {
4650 1.1 mrg /* Non-sequential files don't have an ENDFILE record, so we
4651 1.1 mrg can't be at AFTER_ENDFILE. */
4652 1.1 mrg dtp->u.p.current_unit->endfile = AT_ENDFILE;
4653 1.1 mrg generate_error (&dtp->common, LIBERROR_END, NULL);
4654 1.1 mrg dtp->u.p.current_unit->current_record = 0;
4655 1.1 mrg }
4656 1.1 mrg }
4657