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