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