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